// Copyright (c) 2014, 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 shelf.request;

import 'dart:async';

import 'package:http_parser/http_parser.dart';

import 'hijack_exception.dart';
import 'message.dart';
import 'util.dart';

/// A callback provided by a Shelf handler that's passed to [Request.hijack].
typedef void HijackCallback(
    Stream<List<int>> stream, StreamSink<List<int>> sink);

/// A callback provided by a Shelf adapter that's used by [Request.hijack] to
/// provide a [HijackCallback] with a socket.
typedef void OnHijackCallback(HijackCallback callback);

/// Represents an HTTP request to be processed by a Shelf application.
class Request extends Message {
  /// The remainder of the [requestedUri] path and query designating the virtual
  /// "location" of the request's target within the handler.
  ///
  /// [url] may be an empty, if [requestedUri]targets the handler
  /// root and does not have a trailing slash.
  ///
  /// [url] is never null. If it is not empty, it will start with `/`.
  ///
  /// [scriptName] and [url] combine to create a valid path that should
  /// correspond to the [requestedUri] path.
  final Uri url;

  /// The HTTP request method, such as "GET" or "POST".
  final String method;

  /// The initial portion of the [requestedUri] path that corresponds to the
  /// handler.
  ///
  /// [scriptName] allows a handler to know its virtual "location".
  ///
  /// If the handler corresponds to the "root" of a server, it will be an
  /// empty string, otherwise it will start with a `/`
  ///
  /// [scriptName] and [url] combine to create a valid path that should
  /// correspond to the [requestedUri] path.
  final String scriptName;

  /// The HTTP protocol version used in the request, either "1.0" or "1.1".
  final String protocolVersion;

  /// The original [Uri] for the request.
  final Uri requestedUri;

  /// The callback wrapper for hijacking this request.
  ///
  /// This will be `null` if this request can't be hijacked.
  final _OnHijack _onHijack;

  /// Whether this request can be hijacked.
  ///
  /// This will be `false` either if the adapter doesn't support hijacking, or
  /// if the request has already been hijacked.
  bool get canHijack => _onHijack != null && !_onHijack.called;

  /// If this is non-`null` and the requested resource hasn't been modified
  /// since this date and time, the server should return a 304 Not Modified
  /// response.
  ///
  /// This is parsed from the If-Modified-Since header in [headers]. If
  /// [headers] doesn't have an If-Modified-Since header, this will be `null`.
  DateTime get ifModifiedSince {
    if (_ifModifiedSinceCache != null) return _ifModifiedSinceCache;
    if (!headers.containsKey('if-modified-since')) return null;
    _ifModifiedSinceCache = parseHttpDate(headers['if-modified-since']);
    return _ifModifiedSinceCache;
  }
  DateTime _ifModifiedSinceCache;

  /// Creates a new [Request].
  ///
  /// If [url] and [scriptName] are omitted, they are inferred from
  /// [requestedUri].
  ///
  /// Setting one of [url] or [scriptName] and not the other will throw an
  /// [ArgumentError].
  ///
  /// The default value for [protocolVersion] is '1.1'.
  ///
  /// ## `onHijack`
  ///
  /// [onHijack] allows handlers to take control of the underlying socket for
  /// the request. It should be passed by adapters that can provide access to
  /// the bidirectional socket underlying the HTTP connection stream.
  ///
  /// The [onHijack] callback will only be called once per request. It will be
  /// passed another callback which takes a byte stream and a byte sink.
  /// [onHijack] must pass the stream and sink for the connection stream to this
  /// callback, although it may do so asynchronously. Both parameters may be the
  /// same object. If the user closes the sink, the adapter should ensure that
  /// the stream is closed as well.
  ///
  /// If a request is hijacked, the adapter should expect to receive a
  /// [HijackException] from the handler. This is a special exception used to
  /// indicate that hijacking has occurred. The adapter should avoid either
  /// sending a response or notifying the user of an error if a
  /// [HijackException] is caught.
  ///
  /// An adapter can check whether a request was hijacked using [canHijack],
  /// which will be `false` for a hijacked request. The adapter may throw an
  /// error if a [HijackException] is received for a non-hijacked request, or if
  /// no [HijackException] is received for a hijacked request.
  ///
  /// See also [hijack].
  // TODO(kevmoo) finish documenting the rest of the arguments.
  Request(this.method, Uri requestedUri, {String protocolVersion,
    Map<String, String> headers, Uri url, String scriptName,
    Stream<List<int>> body, Map<String, Object> context,
    OnHijackCallback onHijack})
      : this.requestedUri = requestedUri,
        this.protocolVersion = protocolVersion == null ?
            '1.1' : protocolVersion,
        this.url = _computeUrl(requestedUri, url, scriptName),
        this.scriptName = _computeScriptName(requestedUri, url, scriptName),
        this._onHijack = onHijack == null ? null : new _OnHijack(onHijack),
        super(body == null ? new Stream.fromIterable([]) : body,
            headers: headers, context: context) {
    if (method.isEmpty) throw new ArgumentError('method cannot be empty.');

    if (!requestedUri.isAbsolute) {
      throw new ArgumentError('requstedUri must be an absolute URI.');
    }

    if (this.scriptName.isNotEmpty && !this.scriptName.startsWith('/')) {
      throw new ArgumentError('scriptName must be empty or start with "/".');
    }

    if (this.scriptName == '/') {
      throw new ArgumentError(
          'scriptName can never be "/". It should be empty instead.');
    }

    if (this.scriptName.endsWith('/')) {
      throw new ArgumentError('scriptName must not end with "/".');
    }

    if (this.url.path.isNotEmpty && !this.url.path.startsWith('/')) {
      throw new ArgumentError('url must be empty or start with "/".');
    }

    if (this.scriptName.isEmpty && this.url.path.isEmpty) {
      throw new ArgumentError('scriptName and url cannot both be empty.');
    }
  }

  /// Creates a new [Request] by copying existing values and applying specified
  /// changes.
  ///
  /// New key-value pairs in [context] and [headers] will be added to the copied
  /// [Request].
  ///
  /// If [context] or [headers] includes a key that already exists, the
  /// key-value pair will replace the corresponding entry in the copied
  /// [Request].
  ///
  /// All other context and header values from the [Request] will be included
  /// in the copied [Request] unchanged.
  Request change({Map<String, String> headers, Map<String, Object> context}) {
    headers = updateMap(this.headers, headers);
    context = updateMap(this.context, context);

    return new Request(this.method, this.requestedUri,
        protocolVersion: this.protocolVersion, headers: headers, url: this.url,
        scriptName: this.scriptName, body: this.read(), context: context);
  }

  /// Takes control of the underlying request socket.
  ///
  /// Synchronously, this throws a [HijackException] that indicates to the
  /// adapter that it shouldn't emit a response itself. Asynchronously,
  /// [callback] is called with a [Stream<List<int>>] and
  /// [StreamSink<List<int>>], respectively, that provide access to the
  /// underlying request socket.
  ///
  /// If the sink is closed, the stream will be closed as well. The stream and
  /// sink may be the same object, as in the case of a `dart:io` `Socket`
  /// object.
  ///
  /// This may only be called when using a Shelf adapter that supports
  /// hijacking, such as the `dart:io` adapter. In addition, a given request may
  /// only be hijacked once. [canHijack] can be used to detect whether this
  /// request can be hijacked.
  void hijack(HijackCallback callback) {
    if (_onHijack == null) {
      throw new StateError("This request can't be hijacked.");
    }

    _onHijack.run(callback);
    throw const HijackException();
  }
}

/// A class containing a callback for [Request.hijack] that also tracks whether
/// the callback has been called.
class _OnHijack {
  /// The callback.
  final OnHijackCallback _callback;

  /// Whether [this] has been called.
  bool called = false;

  _OnHijack(this._callback);

  /// Calls [this].
  ///
  /// Throws a [StateError] if [this] has already been called.
  void run(HijackCallback callback) {
    if (called) throw new StateError("This request has already been hijacked.");
    called = true;
    newFuture(() => _callback(callback));
  }
}

/// Computes `url` from the provided [Request] constructor arguments.
///
/// If [url] and [scriptName] are `null`, infer value from [requestedUrl],
/// otherwise return [url].
///
/// If [url] is provided, but [scriptName] is omitted, throws an
/// [ArgumentError].
Uri _computeUrl(Uri requestedUri, Uri url, String scriptName) {
  if (url == null && scriptName == null) {
    return new Uri(path: requestedUri.path, query: requestedUri.query,
        fragment: requestedUri.fragment);
  }

  if (url != null && scriptName != null) {
    if (url.scheme.isNotEmpty) throw new ArgumentError('url must be relative.');
    return url;
  }

  throw new ArgumentError(
      'url and scriptName must both be null or both be set.');
}

/// Computes `scriptName` from the provided [Request] constructor arguments.
///
/// If [url] and [scriptName] are `null` it returns an empty string, otherwise
/// [scriptName] is returned.
///
/// If [script] is provided, but [url] is omitted, throws an
/// [ArgumentError].
String _computeScriptName(Uri requstedUri, Uri url, String scriptName) {
  if (url == null && scriptName == null) {
    return '';
  }

  if (url != null && scriptName != null) {
    return scriptName;
  }

  throw new ArgumentError(
      'url and scriptName must both be null or both be set.');
}
