// Copyright 2014 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 'package:collection/collection.dart';

/// The HTTP verb for a [FakeRequest].
enum HttpMethod {
  get,
  put,
  delete,
  post,
  patch,
  head,
}

HttpMethod _fromMethodString(String value) {
  final String name = value.toLowerCase();
  switch (name) {
    case 'get':
      return HttpMethod.get;
    case 'put':
      return HttpMethod.put;
    case 'delete':
      return HttpMethod.delete;
    case 'post':
      return HttpMethod.post;
    case 'patch':
      return HttpMethod.patch;
    case 'head':
      return HttpMethod.head;
    default:
      throw StateError('Unrecognized HTTP method $value');
  }
}

String _toMethodString(HttpMethod method) {
  switch (method) {
    case HttpMethod.get:
      return 'GET';
    case HttpMethod.put:
      return 'PUT';
    case HttpMethod.delete:
      return 'DELETE';
    case HttpMethod.post:
      return 'POST';
    case HttpMethod.patch:
      return 'PATCH';
    case HttpMethod.head:
      return 'HEAD';
  }
}

/// Override the creation of all [HttpClient] objects with a zone injection.
///
/// This should only be used when the http client cannot be set directly, such as
/// when testing `package:http` code.
Future<void> overrideHttpClients(Future<void> Function() callback,  FakeHttpClient httpClient) async {
  final HttpOverrides overrides = _FakeHttpClientOverrides(httpClient);
  await HttpOverrides.runWithHttpOverrides(callback, overrides);
}

class _FakeHttpClientOverrides extends HttpOverrides {
  _FakeHttpClientOverrides(this.httpClient);

  final FakeHttpClient httpClient;

  @override
  HttpClient createHttpClient(SecurityContext? context) {
    return httpClient;
  }
}

/// Create a fake request that configures the [FakeHttpClient] to respond
/// with the provided [response].
///
/// By default, returns a response with a 200 OK status code and an
/// empty response. If [responseError] is non-null, will throw this instead
/// of returning the response when closing the request.
class FakeRequest {
  const FakeRequest(this.uri, {
    this.method = HttpMethod.get,
    this.response = FakeResponse.empty,
    this.responseError,
    this.body,
  });

  final Uri uri;
  final HttpMethod method;
  final FakeResponse response;
  final Object? responseError;
  final List<int>? body;

  @override
  String toString() => 'Request{${_toMethodString(method)}, $uri}';
}

/// The response the server will create for a given [FakeRequest].
class FakeResponse {
  const FakeResponse({
    this.statusCode = HttpStatus.ok,
    this.body = const <int>[],
    this.headers = const <String, List<String>>{},
  });

  static const FakeResponse empty = FakeResponse();

  final int statusCode;
  final List<int> body;
  final Map<String, List<String>> headers;
}

/// A fake implementation of the HttpClient used for testing.
///
/// This does not fully implement the HttpClient. If an additional method
/// is actually needed by the test script, then it should be added here
/// instead of in another fake.
class FakeHttpClient implements HttpClient {
  /// Creates an HTTP client that responses to each provided
  /// fake request with the provided fake response.
  ///
  /// This does not enforce any order on the requests, but if multiple
  /// requests match then the first will be selected;
  FakeHttpClient.list(List<FakeRequest> requests)
    : _requests = requests.toList();

  /// Creates an HTTP client that always returns an empty 200 request.
  FakeHttpClient.any() : _any = true, _requests = <FakeRequest>[];

  bool _any = false;
  final List<FakeRequest> _requests;

  @override
  bool autoUncompress = true;

  @override
  Duration? connectionTimeout;

  @override
  Duration idleTimeout = Duration.zero;

  @override
  int? maxConnectionsPerHost;

  @override
  String? userAgent;

  @override
  void addCredentials(Uri url, String realm, HttpClientCredentials credentials) {
    throw UnimplementedError();
  }

  @override
  void addProxyCredentials(String host, int port, String realm, HttpClientCredentials credentials) {
    throw UnimplementedError();
  }

  @override
  set authenticate(Future<bool> Function(Uri url, String scheme, String realm)? f) {
    throw UnimplementedError();
  }

  @override
  set authenticateProxy(Future<bool> Function(String host, int port, String scheme, String realm)? f) {
    throw UnimplementedError();
  }

  @override
  set badCertificateCallback(bool Function(X509Certificate cert, String host, int port)? callback) {
    throw UnimplementedError();
  }

  @override
  void close({bool force = false}) { }

  @override
  Future<HttpClientRequest> delete(String host, int port, String path) {
    final Uri uri = Uri(host: host, port: port, path: path);
    return deleteUrl(uri);
  }

  @override
  Future<HttpClientRequest> deleteUrl(Uri url) async {
    return _findRequest(HttpMethod.delete, url, StackTrace.current);
  }

  @override
  set findProxy(String Function(Uri url)? f) { }

  @override
  Future<HttpClientRequest> get(String host, int port, String path) {
    final Uri uri = Uri(host: host, port: port, path: path);
    return getUrl(uri);
  }

  @override
  Future<HttpClientRequest> getUrl(Uri url) async {
    return _findRequest(HttpMethod.get, url, StackTrace.current);
  }

  @override
  Future<HttpClientRequest> head(String host, int port, String path) {
    final Uri uri = Uri(host: host, port: port, path: path);
    return headUrl(uri);
  }

  @override
  Future<HttpClientRequest> headUrl(Uri url) async {
    return _findRequest(HttpMethod.head, url, StackTrace.current);
  }

  @override
  Future<HttpClientRequest> open(String method, String host, int port, String path) {
    final Uri uri = Uri(host: host, port: port, path: path);
    return openUrl(method, uri);
  }

  @override
  Future<HttpClientRequest> openUrl(String method, Uri url) async {
    return _findRequest(_fromMethodString(method), url, StackTrace.current);
  }

  @override
  Future<HttpClientRequest> patch(String host, int port, String path) {
    final Uri uri = Uri(host: host, port: port, path: path);
    return patchUrl(uri);
  }

  @override
  Future<HttpClientRequest> patchUrl(Uri url) async {
    return _findRequest(HttpMethod.patch, url, StackTrace.current);
  }

  @override
  Future<HttpClientRequest> post(String host, int port, String path) {
    final Uri uri = Uri(host: host, port: port, path: path);
    return postUrl(uri);
  }

  @override
  Future<HttpClientRequest> postUrl(Uri url) async {
    return _findRequest(HttpMethod.post, url, StackTrace.current);
  }

  @override
  Future<HttpClientRequest> put(String host, int port, String path) {
    final Uri uri = Uri(host: host, port: port, path: path);
    return putUrl(uri);
  }

  @override
  Future<HttpClientRequest> putUrl(Uri url) async {
    return _findRequest(HttpMethod.put, url, StackTrace.current);
  }

  int _requestCount = 0;

  _FakeHttpClientRequest _findRequest(HttpMethod method, Uri uri, StackTrace stackTrace) {
    // Ensure the fake client throws similar errors to the real client.
    if (uri.host.isEmpty) {
      throw ArgumentError('No host specified in URI $uri');
    } else if (uri.scheme != 'http' && uri.scheme != 'https') {
      throw ArgumentError("Unsupported scheme '${uri.scheme}' in URI $uri");
    }
    final String methodString = _toMethodString(method);
    if (_any) {
      return _FakeHttpClientRequest(
        FakeResponse.empty,
        uri,
        methodString,
        null,
        null,
        stackTrace,
      );
    }
    FakeRequest? matchedRequest;
    for (final FakeRequest request in _requests) {
      if (request.method == method && request.uri.toString() == uri.toString()) {
        matchedRequest = request;
        break;
      }
    }
    if (matchedRequest == null) {
      throw StateError(
        'Unexpected request for $method to $uri after $_requestCount requests.\n'
        'Pending requests: ${_requests.join(',')}'
      );
    }
    _requestCount += 1;
    _requests.remove(matchedRequest);
    return _FakeHttpClientRequest(
      matchedRequest.response,
      uri,
      methodString,
      matchedRequest.responseError,
      matchedRequest.body,
      stackTrace,
    );
  }
}

class _FakeHttpClientRequest implements HttpClientRequest {
  _FakeHttpClientRequest(this._response, this._uri, this._method, this._responseError, this._expectedBody, this._stackTrace);

  final FakeResponse _response;
  final String _method;
  final Uri _uri;
  final Object? _responseError;
  final List<int> _body = <int>[];
  final List<int>? _expectedBody;
  final StackTrace _stackTrace;

  @override
  bool bufferOutput = true;

  @override
  int contentLength = 0;

  @override
  late Encoding encoding;

  @override
  bool followRedirects = true;

  @override
  int maxRedirects = 5;

  @override
  bool persistentConnection = true;

  @override
  void abort([Object? exception, StackTrace? stackTrace]) {
    throw UnimplementedError();
  }

  @override
  void add(List<int> data) {
    _body.addAll(data);
  }

  @override
  void addError(Object error, [StackTrace? stackTrace]) { }

  @override
  Future<void> addStream(Stream<List<int>> stream) async {
    final Completer<void> completer = Completer<void>();
    stream.listen(_body.addAll, onDone: completer.complete);
    await completer.future;
  }

  @override
  Future<HttpClientResponse> close() async {
    final Completer<void> completer = Completer<void>();
    Timer.run(() {
      if (_expectedBody != null && !const ListEquality<int>().equals(_expectedBody, _body)) {
        completer.completeError(StateError(
          'Expected a request with the following body:\n$_expectedBody\n but found:\n$_body'
        ), _stackTrace);
      } else {
        completer.complete();
      }
    });
    await completer.future;
    if (_responseError != null) {
      return Future<HttpClientResponse>.error(_responseError!);
    }
    return _FakeHttpClientResponse(_response);
  }

  @override
  HttpConnectionInfo get connectionInfo => throw UnimplementedError();

  @override
  List<Cookie> get cookies => throw UnimplementedError();

  @override
  Future<HttpClientResponse> get done => throw UnimplementedError();

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

  @override
  final HttpHeaders headers = _FakeHttpHeaders(<String, List<String>>{});

  @override
  String get method => _method;

  @override
  Uri get uri => _uri;

  @override
  void write(Object? object) {
    _body.addAll(utf8.encode(object.toString()));
  }

  @override
  void writeAll(Iterable<dynamic> objects, [String separator = '']) {
    _body.addAll(utf8.encode(objects.join(separator)));
  }

  @override
  void writeCharCode(int charCode) {
    _body.add(charCode);
  }

  @override
  void writeln([Object? object = '']) {
    _body.addAll(utf8.encode('$object\n'));
  }
}

class _FakeHttpClientResponse extends Stream<List<int>> implements HttpClientResponse {
  _FakeHttpClientResponse(this._response)
      : headers = _FakeHttpHeaders(Map<String, List<String>>.from(_response.headers));

  final FakeResponse _response;

  @override
  X509Certificate get certificate => throw UnimplementedError();

  @override
  HttpClientResponseCompressionState get compressionState => throw UnimplementedError();

  @override
  HttpConnectionInfo get connectionInfo => throw UnimplementedError();

  @override
  int get contentLength => _response.body.length;

  @override
  List<Cookie> get cookies => throw UnimplementedError();

  @override
  Future<Socket> detachSocket() {
    throw UnimplementedError();
  }

  @override
  final HttpHeaders headers;

  @override
  bool get isRedirect => throw UnimplementedError();

  @override
  StreamSubscription<List<int>> listen(
    void Function(List<int> event)? onData, {
    Function? onError,
    void Function()? onDone,
    bool? cancelOnError,
  }) {
    final Stream<List<int>> response = Stream<List<int>>.fromIterable(<List<int>>[
      _response.body,
    ]);
    return response.listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError);
  }

  @override
  bool get persistentConnection => throw UnimplementedError();

  @override
  String get reasonPhrase => 'OK';

  @override
  Future<HttpClientResponse> redirect([String? method, Uri? url, bool? followLoops]) {
    throw UnimplementedError();
  }

  @override
  List<RedirectInfo> get redirects => throw UnimplementedError();

  @override
  int get statusCode => _response.statusCode;
}

class _FakeHttpHeaders extends HttpHeaders {
  _FakeHttpHeaders(this._backingData);

  final Map<String, List<String>> _backingData;

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

  @override
  void add(String name, Object value, {bool preserveHeaderCase = false}) {
    _backingData[name] ??= <String>[];
    _backingData[name]!.add(value.toString());
  }

  @override
  void clear() {
    _backingData.clear();
  }

  @override
  void forEach(void Function(String name, List<String> values) action) { }

  @override
  void noFolding(String name) {  }

  @override
  void remove(String name, Object value) {
    _backingData[name]?.remove(value.toString());
  }

  @override
  void removeAll(String name) {
    _backingData.remove(name);
  }

  @override
  void set(String name, Object value, {bool preserveHeaderCase = false}) {
    _backingData[name] = <String>[value.toString()];
  }

  @override
  String? value(String name) {
    return _backingData[name]?.join('; ');
  }
}
