// Copyright 2019 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';

import 'package:meta/meta.dart';

typedef ContentLengthProvider = int Function();

@immutable
class _Body {
  _Body.empty()
      : isUtf8 = true,
        value = null,
        bytes = Uint8List(0),
        stream = Stream<Uint8List>.fromIterable(const Iterable<Uint8List>.empty());

  _Body.utf8(String this.value)
      : isUtf8 = true,
        bytes = utf8.encode(value) as Uint8List,
        stream = Stream<Uint8List>.fromIterable(<Uint8List>[utf8.encode(value) as Uint8List]);

  _Body.rawBytes(this.bytes)
      : isUtf8 = false,
        value = null,
        stream = Stream<Uint8List>.fromIterable(<Uint8List>[bytes]);

  _Body.copy(_Body other)
      : isUtf8 = other.isUtf8,
        value = other.value,
        bytes = other.bytes,
        stream = Stream<Uint8List>.fromIterable(<Uint8List>[other.bytes]);

  final bool isUtf8;
  final String? value;
  final Uint8List bytes;
  final Stream<Uint8List> stream;
}

abstract class FakeTransport {
  int get contentLength;

  HttpConnectionInfo? get connectionInfo => null;

  final List<FakeCookie> cookies = <FakeCookie>[];

  FakeHttpHeaders get headers {
    _headers ??= FakeHttpHeaders(contentLengthProvider: () => contentLength);
    return _headers!;
  }

  FakeHttpHeaders? _headers;

  bool get persistentConnection => false;
}

// TODO(tvolkert): `implements Stream<Uint8List>` once HttpClientResponse does the same
abstract class FakeInbound extends FakeTransport {
  FakeInbound(String? body) : _body = body == null ? _Body.empty() : _Body.utf8(body);

  /// Indicates whether the body stream has been exposed to callers in any way.
  /// Once the body stream has been exposed to callers, [body] becomes
  /// immutable.
  bool _isStreamExposed = false;

  /// Resets this transport so that it may be reused.
  @mustCallSuper
  void reset() {
    _body = _Body.copy(_body);
    _isStreamExposed = false;
  }

  /// The UTF-8 encoded value of the HTTP request body, or null if this request
  /// specifies no body.
  ///
  /// If the HTTP request body was set via [bodyBytes], then it's assumed that
  /// the body is not a UTF-8 encoded string, and subsequently attempting to
  /// access [body] will throw a [StateError].
  ///
  /// Once the body stream has been exposed to callers in any way, the [body]
  /// value becomes immutable (as does the [bodyBytes] value), and any attempt
  /// to modify it will throw a [StateError].
  String? get body {
    if (!_body.isUtf8) {
      throw StateError('body is not a valid UTF-8 string');
    }
    return _body.value;
  }

  _Body _body;
  set body(String? value) {
    if (_isStreamExposed) {
      throw StateError('The body of this transport has been made immutable');
    }
    _body = value == null ? _Body.empty() : _Body.utf8(value);
  }

  /// The raw bytes of the HTTP request body.
  ///
  /// This will never be null; if the HTTP request body is empty, this will be
  /// the empty list.
  ///
  /// Setting this value directly will be assumed to be because the bytes are
  /// not a UTF-8 encoded string, and subsequently attempting to access [body]
  /// will throw a [StateError].
  ///
  /// Once the body stream has been exposed to callers in any way, the
  /// [bodyBytes] value becomes immutable (as does the [body] value), and any
  /// attempt to modify it will throw a [StateError].
  Uint8List get bodyBytes => _body.bytes;
  set bodyBytes(Uint8List value) {
    if (_isStreamExposed) {
      throw StateError('The body of this transport has been made immutable');
    }
    _body = _Body.rawBytes(value);
  }

  StreamSubscription<Uint8List> listen(
    void Function(Uint8List event)? onData, {
    Function? onError,
    void Function()? onDone,
    bool? cancelOnError,
  }) {
    _isStreamExposed = true;
    return _body.stream.listen(
      onData,
      onError: onError,
      onDone: onDone,
      cancelOnError: cancelOnError,
    );
  }

  Future<bool> any(bool Function(Uint8List element) test) {
    _isStreamExposed = true;
    return _body.stream.any(test);
  }

  Stream<Uint8List> asBroadcastStream({
    void Function(StreamSubscription<Uint8List> subscription)? onListen,
    void Function(StreamSubscription<Uint8List> subscription)? onCancel,
  }) {
    _isStreamExposed = true;
    return _body.stream.asBroadcastStream(onListen: onListen, onCancel: onCancel);
  }

  Stream<E> asyncExpand<E>(Stream<E>? Function(Uint8List event) convert) {
    _isStreamExposed = true;
    return _body.stream.asyncExpand<E>(convert);
  }

  Stream<E> asyncMap<E>(FutureOr<E> Function(Uint8List event) convert) {
    _isStreamExposed = true;
    return _body.stream.asyncMap<E>(convert);
  }

  Stream<R> cast<R>() {
    _isStreamExposed = true;
    return _body.stream.cast<R>();
  }

  Future<bool> contains(Object? needle) {
    _isStreamExposed = true;
    return _body.stream.contains(needle);
  }

  Stream<Uint8List> distinct([bool Function(Uint8List previous, Uint8List next)? equals]) {
    _isStreamExposed = true;
    return _body.stream.distinct(equals);
  }

  Future<E> drain<E>([E? futureValue]) {
    _isStreamExposed = true;
    return _body.stream.drain<E>(futureValue);
  }

  Future<Uint8List> elementAt(int index) {
    _isStreamExposed = true;
    return _body.stream.elementAt(index);
  }

  Future<bool> every(bool Function(Uint8List element) test) {
    _isStreamExposed = true;
    return _body.stream.every(test);
  }

  Stream<S> expand<S>(Iterable<S> Function(Uint8List element) convert) {
    _isStreamExposed = true;
    return _body.stream.expand(convert);
  }

  Future<Uint8List> get first {
    _isStreamExposed = true;
    return _body.stream.first;
  }

  Future<Uint8List> firstWhere(
    bool Function(Uint8List element) test, {
    List<int> Function()? orElse,
  }) {
    _isStreamExposed = true;
    return _body.stream.firstWhere(test, orElse: () => Uint8List.fromList(orElse!()));
  }

  Future<S> fold<S>(S initialValue, S Function(S previous, Uint8List element) combine) {
    _isStreamExposed = true;
    return _body.stream.fold<S>(initialValue, combine);
  }

  Future<dynamic> forEach(void Function(Uint8List element) action) {
    _isStreamExposed = true;
    return _body.stream.forEach(action);
  }

  Stream<Uint8List> handleError(
    Function onError, {
    bool Function(dynamic error)? test,
  }) {
    _isStreamExposed = true;
    return _body.stream.handleError(onError, test: test);
  }

  bool get isBroadcast {
    _isStreamExposed = true;
    return _body.stream.isBroadcast;
  }

  Future<bool> get isEmpty {
    _isStreamExposed = true;
    return _body.stream.isEmpty;
  }

  Future<String> join([String separator = '']) {
    _isStreamExposed = true;
    return _body.stream.join(separator);
  }

  Future<Uint8List> get last {
    _isStreamExposed = true;
    return _body.stream.last;
  }

  Future<Uint8List> lastWhere(
    bool Function(Uint8List element) test, {
    Uint8List Function()? orElse,
  }) {
    _isStreamExposed = true;
    return _body.stream.lastWhere(test, orElse: () => Uint8List.fromList(orElse!()));
  }

  Future<int> get length {
    _isStreamExposed = true;
    return _body.stream.length;
  }

  Stream<S> map<S>(S Function(Uint8List event) convert) {
    _isStreamExposed = true;
    return _body.stream.map<S>(convert);
  }

  Future<dynamic> pipe(StreamConsumer<Uint8List> streamConsumer) {
    _isStreamExposed = true;
    return _body.stream.map((Uint8List list) => list.toList()).pipe(streamConsumer);
  }

  Future<Uint8List> reduce(List<int> Function(Uint8List previous, Uint8List element) combine) {
    _isStreamExposed = true;
    return _body.stream
        .reduce((Uint8List previous, Uint8List element) => Uint8List.fromList(combine(previous, element)));
  }

  Future<Uint8List> get single {
    _isStreamExposed = true;
    return _body.stream.single;
  }

  Future<Uint8List> singleWhere(
    bool Function(Uint8List element) test, {
    List<int> Function()? orElse,
  }) {
    _isStreamExposed = true;
    return _body.stream.singleWhere(test, orElse: () => Uint8List.fromList(orElse!()));
  }

  Stream<Uint8List> skip(int count) {
    _isStreamExposed = true;
    return _body.stream.skip(count);
  }

  Stream<Uint8List> skipWhile(bool Function(Uint8List element) test) {
    _isStreamExposed = true;
    return _body.stream.skipWhile(test);
  }

  Stream<Uint8List> take(int count) {
    _isStreamExposed = true;
    return _body.stream.take(count);
  }

  Stream<Uint8List> takeWhile(bool Function(Uint8List element) test) {
    _isStreamExposed = true;
    return _body.stream.takeWhile(test);
  }

  Stream<Uint8List> timeout(
    Duration timeLimit, {
    void Function(EventSink<Uint8List> sink)? onTimeout,
  }) {
    _isStreamExposed = true;
    return _body.stream.timeout(timeLimit, onTimeout: onTimeout);
  }

  Future<List<Uint8List>> toList() {
    _isStreamExposed = true;
    return _body.stream.toList();
  }

  Future<Set<Uint8List>> toSet() {
    _isStreamExposed = true;
    return _body.stream.toSet();
  }

  Stream<S> transform<S>(StreamTransformer<List<int>, S> streamTransformer) {
    _isStreamExposed = true;
    return _body.stream.map((Uint8List list) => list.toList()).transform<S>(streamTransformer);
  }

  Stream<Uint8List> where(bool Function(Uint8List event) test) {
    _isStreamExposed = true;
    return _body.stream.where(test);
  }

  @override
  int get contentLength => _body.bytes.length;

  X509Certificate? get certificate => null;
}

abstract class FakeOutbound extends FakeTransport implements IOSink {
  StringBuffer _buffer = StringBuffer();

  String get body => _buffer.toString();

  List<Object> get errors => _errors;
  List<Object> _errors = <Object>[];

  /// Whether this outbound has been closed.
  bool get isClosed => _isClosed;
  bool _isClosed = false;

  /// Resets this transport so that it may be reused.
  @mustCallSuper
  void reset() {
    _isClosed = false;
    _buffer = StringBuffer();
    _errors = <Object>[];
  }

  @override
  Encoding get encoding => utf8;

  @override
  set encoding(Encoding value) => throw UnsupportedError('Unsupported');

  @override
  void add(List<int> data) {
    if (isClosed) {
      throw StateError('Transport is closed');
    }
    headers._sealed = true;
    _buffer.write(utf8.decode(data));
  }

  @override
  void addError(Object error, [StackTrace? stackTrace]) {
    if (isClosed) {
      throw StateError('Transport is closed');
    }
    errors.add(error);
  }

  @override
  Future<dynamic> addStream(Stream<List<int>> stream) async {
    if (isClosed) {
      throw StateError('Transport is closed');
    }
    headers._sealed = true;
    _buffer.write(await utf8.decoder.bind(stream).join());
  }

  @override
  void write(Object? obj) {
    if (isClosed) {
      throw StateError('Transport is closed');
    }
    headers._sealed = true;
    _buffer.write(obj);
  }

  @override
  void writeAll(Iterable<dynamic> objects, [String separator = '']) {
    if (isClosed) {
      throw StateError('Transport is closed');
    }
    headers._sealed = true;
    _buffer.writeAll(objects, separator);
  }

  @override
  void writeCharCode(int charCode) {
    if (isClosed) {
      throw StateError('Transport is closed');
    }
    headers._sealed = true;
    _buffer.writeCharCode(charCode);
  }

  @override
  void writeln([Object? obj = '']) {
    if (isClosed) {
      throw StateError('Transport is closed');
    }
    headers._sealed = true;
    _buffer.writeln(obj);
  }

  @override
  Future<dynamic> get done async {}

  @override
  Future<dynamic> flush() async {}

  @override
  Future<dynamic> close() async {
    _isClosed = true;
  }

  bool get bufferOutput => false;

  set bufferOutput(bool value) => throw UnsupportedError('Unsupported');

  @override
  int get contentLength => _contentLength ?? _buffer.length;
  int? _contentLength;

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

  set persistentConnection(bool value) => throw UnsupportedError('Unsupported');
}

class FakeCookie implements Cookie {
  FakeCookie({
    required this.name,
    required this.value,
    this.domain,
    this.path,
    this.expires,
    required this.httpOnly,
    this.maxAge,
    required this.secure,
  });

  @override
  String name;

  @override
  String value;

  @override
  String? domain;

  @override
  String? path;

  @override
  DateTime? expires;

  @override
  bool httpOnly;

  @override
  int? maxAge;

  @override
  bool secure;
}

class FakeHttpHeaders implements HttpHeaders {
  FakeHttpHeaders({this.contentLengthProvider});

  final ContentLengthProvider? contentLengthProvider;
  final Map<String, List<String>> _values = <String, List<String>>{};
  bool _sealed = false;

  void _checkSealed() {
    if (_sealed) {
      throw StateError('HTTP headers are sealed');
    }
  }

  @override
  bool get chunkedTransferEncoding => false;

  @override
  set chunkedTransferEncoding(bool value) => throw UnsupportedError('Unsupported');

  @override
  int get contentLength => contentLengthProvider != null ? contentLengthProvider!() : -1;

  @override
  set contentLength(int value) => throw UnsupportedError('Unsupported');

  @override
  ContentType get contentType => throw UnimplementedError();

  @override
  set contentType(ContentType? value) {
    _checkSealed();
    removeAll(HttpHeaders.contentTypeHeader);
    add(HttpHeaders.contentTypeHeader, '$value');
  }

  @override
  DateTime? date;

  @override
  DateTime? expires;

  @override
  String? host;

  @override
  DateTime? ifModifiedSince;

  @override
  late bool persistentConnection;

  @override
  int? port;

  @override
  List<String>? operator [](String name) => _values[name];

  @override
  void add(String name, Object value, {bool preserveHeaderCase = false}) {
    _checkSealed();
    name = name.toLowerCase();
    _values[name] ??= <String>[];
    _values[name]!.add('$value');
  }

  @override
  void clear() {
    _checkSealed();
    _values.clear();
  }

  @override
  void forEach(void Function(String name, List<String> values) f) {
    _values.forEach(f);
  }

  @override
  void noFolding(String name) {}

  @override
  void remove(String name, Object value) {
    _checkSealed();
    name = name.toLowerCase();
    if (_values.containsKey('$value')) {
      _values[name]!.remove('$value');
    }
  }

  @override
  void removeAll(String name) {
    _checkSealed();
    name = name.toLowerCase();
    _values.remove(name);
  }

  @override
  void set(String name, Object value, {bool preserveHeaderCase = false}) {
    _checkSealed();
    name = name.toLowerCase();
    _values[name] = <String>['$value'];
  }

  @override
  String? value(String name) {
    final List<String>? value = _values[name.toLowerCase()];
    return value?.single;
  }
}

class FakeHttpRequest extends FakeInbound implements HttpRequest {
  /// Creates a new [FakeHttpRequest].
  ///
  /// If the optional [body] argument is specified, the request stream will
  /// yield the specified body value when UTF-8 decoded. By default, the
  /// request stream will be empty. The [body] property can be modified until
  /// the stream has been exposed to callers, at which time it becomes
  /// immutable.
  FakeHttpRequest({
    this.method = 'GET',
    String? body,
    String path = '/',
    Map<String, dynamic>? queryParametersValue,
    FakeHttpResponse? response,
  })  : uri = Uri(path: path, queryParameters: queryParametersValue),
        response = response ?? FakeHttpResponse(),
        super(body);

  @override
  String method;

  @override
  Uri uri;

  String get path => uri.path;
  set path(String value) {
    uri = uri.replace(path: value);
  }

  @override
  FakeHttpResponse response;

  @override
  String get protocolVersion => '1.1';

  @override
  Uri get requestedUri => uri;

  @override
  HttpSession get session => throw UnsupportedError('Unsupported');
}

class FakeHttpResponse extends FakeOutbound implements HttpResponse {
  @override
  Duration? get deadline => null;

  @override
  set deadline(Duration? value) => throw UnsupportedError('Unsupported');

  @override
  String get reasonPhrase => 'reason';

  @override
  set reasonPhrase(String value) => throw UnsupportedError('Unsupported');

  @override
  int statusCode = HttpStatus.ok;

  @override
  Future<dynamic> redirect(Uri location, {int status = HttpStatus.movedTemporarily}) {
    statusCode = status;
    headers.add(HttpHeaders.locationHeader, '$location');
    return close();
  }

  @override
  Future<Socket> detachSocket({bool writeHeaders = true}) => throw UnsupportedError('Unsupported');
}
