// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library base_request;

import 'dart:async';
import 'dart:io';
import 'dart:isolate';
import 'dart:uri';

import 'byte_stream.dart';
import 'client.dart';
import 'streamed_response.dart';
import 'utils.dart';

/// The base class for HTTP requests.
///
/// Subclasses of [BaseRequest] can be constructed manually and passed to
/// [BaseClient.send], which allows the user to provide fine-grained control
/// over the request properties. However, usually it's easier to use convenience
/// methods like [get] or [BaseClient.get].
abstract class BaseRequest {
  /// The HTTP method of the request. Most commonly "GET" or "POST", less
  /// commonly "HEAD", "PUT", or "DELETE". Non-standard method names are also
  /// supported.
  final String method;

  /// The URL to which the request will be sent.
  final Uri url;

  /// The size of the request body, in bytes. This defaults to -1, which
  /// indicates that the size of the request is not known in advance.
  int get contentLength => _contentLength;
  int _contentLength = -1;

  set contentLength(int value) {
    _checkFinalized();
    _contentLength = value;
  }

  /// Whether a persistent connection should be maintained with the server.
  /// Defaults to true.
  bool get persistentConnection => _persistentConnection;
  bool _persistentConnection = true;

  set persistentConnection(bool value) {
    _checkFinalized();
    _persistentConnection = value;
  }

  /// Whether the client should follow redirects while resolving this request.
  /// Defaults to true.
  bool get followRedirects => _followRedirects;
  bool _followRedirects = true;

  set followRedirects(bool value) {
    _checkFinalized();
    _followRedirects = value;
  }

  /// The maximum number of redirects to follow when [followRedirects] is true.
  /// If this number is exceeded the [BaseResponse] future will signal a
  /// [RedirectLimitExceeded] exception. Defaults to 5.
  int get maxRedirects => _maxRedirects;
  int _maxRedirects = 5;

  set maxRedirects(int value) {
    _checkFinalized();
    _maxRedirects = value;
  }

  // TODO(nweiz): automatically parse cookies from headers

  // TODO(nweiz): make this a HttpHeaders object
  /// The headers for this request.
  final Map<String, String> headers;

  /// Whether the request has been finalized.
  bool get finalized => _finalized;
  bool _finalized = false;

  /// Creates a new HTTP request.
  BaseRequest(this.method, this.url)
    : headers = <String, String>{};

  /// Finalizes the HTTP request in preparation for it being sent. This freezes
  /// all mutable fields and returns a single-subscription [ByteStream] that
  /// emits the body of the request.
  ///
  /// The base implementation of this returns null rather than a [ByteStream];
  /// subclasses are responsible for creating the return value, which should be
  /// single-subscription to ensure that no data is dropped. They should also
  /// freeze any additional mutable fields they add that don't make sense to
  /// change after the request headers are sent.
  ByteStream finalize() {
    // TODO(nweiz): freeze headers
    if (finalized) throw new StateError("Can't finalize a finalized Request.");
    _finalized = true;
    return null;
  }

  /// Sends this request.
  ///
  /// This automatically initializes a new [Client] and closes that client once
  /// the request is complete. If you're planning on making multiple requests to
  /// the same server, you should use a single [Client] for all of those
  /// requests.
  Future<StreamedResponse> send() {
    var client = new Client();
    return client.send(this).then((response) {
      var stream = onDone(response.stream, client.close);
      return new StreamedResponse(
          new ByteStream(stream),
          response.statusCode,
          response.contentLength,
          request: response.request,
          headers: response.headers,
          isRedirect: response.isRedirect,
          persistentConnection: response.persistentConnection,
          reasonPhrase: response.reasonPhrase);
    }).catchError((e) {
      client.close();
      throw e;
    });
  }

  /// Throws an error if this request has been finalized.
  void _checkFinalized() {
    if (!finalized) return;
    throw new StateError("Can't modify a finalized Request.");
  }

  String toString() => "$method $url";
}
