// 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.

import 'base_client.dart';
import 'base_request.dart';
import 'client.dart';
import 'response.dart';
import 'streamed_response.dart';

/// The base class for HTTP responses.
///
/// Subclasses of [BaseResponse] are usually not constructed manually; instead,
/// they're returned by [BaseClient.send] or other HTTP client methods.
abstract class BaseResponse {
  /// The (frozen) request that triggered this response.
  final BaseRequest? request;

  /// The HTTP status code for this response.
  final int statusCode;

  /// The reason phrase associated with the status code.
  final String? reasonPhrase;

  /// The size of the response body, in bytes.
  ///
  /// If the size of the request is not known in advance, this is `null`.
  final int? contentLength;

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

  /// The HTTP headers returned by the server.
  ///
  /// The header names are converted to lowercase and stored with their
  /// associated header values.
  ///
  /// If the server returns multiple headers with the same name then the header
  /// values will be associated with a single key and seperated by commas and
  /// possibly whitespace. For example:
  /// ```dart
  /// // HTTP/1.1 200 OK
  /// // Fruit: Apple
  /// // Fruit: Banana
  /// // Fruit: Grape
  /// final values = response.headers['fruit']!.split(RegExp(r'\s*,\s*'));
  /// // values = ['Apple', 'Banana', 'Grape']
  /// ```
  ///
  /// To retrieve the header values as a `List<String>`, use
  /// [HeadersWithSplitValues.headersSplitValues].
  ///
  /// If a header value contains whitespace then that whitespace may be replaced
  /// by a single space. Leading and trailing whitespace in header values are
  /// always removed.
  final Map<String, String> headers;

  final bool isRedirect;

  /// Whether the server requested that a persistent connection be maintained.
  final bool persistentConnection;

  BaseResponse(this.statusCode,
      {this.contentLength,
      this.request,
      this.headers = const {},
      this.isRedirect = false,
      this.persistentConnection = true,
      this.reasonPhrase}) {
    if (statusCode < 100) {
      throw ArgumentError('Invalid status code $statusCode.');
    } else if (contentLength != null && contentLength! < 0) {
      throw ArgumentError('Invalid content length $contentLength.');
    }
  }
}

/// A [BaseResponse] with a [url] field.
///
/// [Client] methods that return a [BaseResponse] subclass, such as [Response]
/// or [StreamedResponse], **may** return a [BaseResponseWithUrl].
///
/// For example:
///
/// ```dart
/// final client = Client();
/// final response = client.get(Uri.https('example.com', '/'));
/// Uri? finalUri;
/// if (response case BaseResponseWithUrl(:final url)) {
///   finalUri = url;
/// }
/// // Do something with `finalUri`.
/// client.close();
/// ```
///
/// [url] will be added to [BaseResponse] when `package:http` version 2 is
/// released and this mixin will be deprecated.
abstract interface class BaseResponseWithUrl implements BaseResponse {
  /// The [Uri] of the response returned by the server.
  ///
  /// If no redirects were followed, [url] will be the same as the requested
  /// [Uri].
  ///
  /// If redirects were followed, [url] will be the [Uri] of the last redirect
  /// that was followed.
  abstract final Uri url;
}

/// "token" as defined in RFC 2616, 2.2
/// See https://datatracker.ietf.org/doc/html/rfc2616#section-2.2
const _tokenChars = r"!#$%&'*+\-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`"
    'abcdefghijklmnopqrstuvwxyz|~';

/// Splits comma-seperated header values.
var _headerSplitter = RegExp(r'[ \t]*,[ \t]*');

/// Splits comma-seperated "Set-Cookie" header values.
///
/// Set-Cookie strings can contain commas. In particular, the following
/// productions defined in RFC-6265, section 4.1.1:
/// - <sane-cookie-date> e.g. "Expires=Sun, 06 Nov 1994 08:49:37 GMT"
/// - <path-value> e.g. "Path=somepath,"
/// - <extension-av> e.g. "AnyString,Really,"
///
/// Some values are ambiguous e.g.
/// "Set-Cookie: lang=en; Path=/foo/"
/// "Set-Cookie: SID=x23"
/// and:
/// "Set-Cookie: lang=en; Path=/foo/,SID=x23"
/// would both be result in `response.headers` => "lang=en; Path=/foo/,SID=x23"
///
/// The idea behind this regex is that ",<valid token>=" is more likely to
/// start a new <cookie-pair> then be part of <path-value> or <extension-av>.
///
/// See https://datatracker.ietf.org/doc/html/rfc6265#section-4.1.1
var _setCookieSplitter = RegExp(r'[ \t]*,[ \t]*(?=[' + _tokenChars + r']+=)');

extension HeadersWithSplitValues on BaseResponse {
  /// The HTTP headers returned by the server.
  ///
  /// The header names are converted to lowercase and stored with their
  /// associated header values.
  ///
  /// Cookies can be parsed using the dart:io `Cookie` class:
  ///
  /// ```dart
  /// import "dart:io";
  /// import "package:http/http.dart";
  ///
  /// void main() async {
  /// final response = await Client().get(Uri.https('example.com', '/'));
  /// final cookies = [
  ///   for (var value i
  ///       in response.headersSplitValues['set-cookie'] ?? <String>[])
  ///     Cookie.fromSetCookieValue(value)
  /// ];
  Map<String, List<String>> get headersSplitValues {
    var headersWithFieldLists = <String, List<String>>{};
    headers.forEach((key, value) {
      if (!value.contains(',')) {
        headersWithFieldLists[key] = [value];
      } else {
        if (key == 'set-cookie') {
          headersWithFieldLists[key] = value.split(_setCookieSplitter);
        } else {
          headersWithFieldLists[key] = value.split(_headerSplitter);
        }
      }
    });
    return headersWithFieldLists;
  }
}
