// 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 '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
  /// [RedirectException]. 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";
}
