// Copyright 2013 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:mockito/mockito.dart';

class TestHttpOverrides extends HttpOverrides {
  @override
  HttpClient createHttpClient(SecurityContext? context) {
    return createMockImageHttpClient(context);
  }
}

MockHttpClient createMockImageHttpClient(SecurityContext? _) {
  final MockHttpClient client = MockHttpClient();
  final MockHttpClientRequest request = MockHttpClientRequest();
  final MockHttpClientResponse response = MockHttpClientResponse();
  final MockHttpHeaders headers = MockHttpHeaders();

  final List<int> transparentImage = getTestImageData();

  when(client.getUrl(any))
      .thenAnswer((_) => Future<MockHttpClientRequest>.value(request));

  when(request.headers).thenReturn(headers);

  when(request.close())
      .thenAnswer((_) => Future<MockHttpClientResponse>.value(response));

  when(client.autoUncompress = any).thenAnswer((_) => null);

  when(response.contentLength).thenReturn(transparentImage.length);

  when(response.statusCode).thenReturn(HttpStatus.ok);

  when(response.compressionState)
      .thenReturn(HttpClientResponseCompressionState.notCompressed);

  // Define an image stream that streams the mock test image for all
  // image tests that request an image.
  StreamSubscription<List<int>> imageStream(Invocation invocation) {
    final void Function(List<int>)? onData = invocation.positionalArguments[0];
    final void Function()? onDone = invocation.namedArguments[#onDone];
    final void Function(Object, [StackTrace?])? onError =
        invocation.namedArguments[#onError];
    final bool? cancelOnError = invocation.namedArguments[#cancelOnError];

    return Stream<List<int>>.fromIterable(<List<int>>[transparentImage]).listen(
      onData,
      onError: onError,
      onDone: onDone,
      cancelOnError: cancelOnError,
    );
  }

  when(response.listen(any,
          onError: anyNamed('onError'),
          onDone: anyNamed('onDone'),
          cancelOnError: anyNamed('cancelOnError')))
      .thenAnswer(imageStream);

  return client;
}

// This string represents the hexidecial bytes of a transparent image. A
// string is used to make the visual representation of the data compact. A
// List<int> of the same data requires over 60 lines in a source file with
// each element in the array on a single line.
const String _imageBytesAsString = '''
  0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49,
  0x48, 0x44, 0x52, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x08, 0x06,
  0x00, 0x00, 0x00, 0x1F, 0x15, 0xC4, 0x89, 0x00, 0x00, 0x00, 0x0A, 0x49, 0x44,
  0x41, 0x54, 0x78, 0x9C, 0x63, 0x00, 0x01, 0x00, 0x00, 0x05, 0x00, 0x01, 0x0D,
  0x0A, 0x2D, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE,
  ''';

// Convert the string representing the hexidecimal bytes in the image into
// a list of integers that can be consumed as image data in a stream.
final List<int> _transparentImage = const LineSplitter()
    .convert(_imageBytesAsString.replaceAllMapped(
        RegExp(r' *0x([A-F0-9]{2}),? *\n? *'), (Match m) => '${m[1]}\n'))
    .map<int>((String b) => int.parse(b, radix: 16))
    .toList();

List<int> getTestImageData() {
  return _transparentImage;
}

/// Define the "fake" data types to be used in mock data type definitions. These
/// fake data types are important in the definition of the return values of the
/// properties and methods of the mock data types for null safety.
// ignore: avoid_implementing_value_types
class _FakeDuration extends Fake implements Duration {}

class _FakeHttpClientRequest extends Fake implements HttpClientRequest {}

class _FakeUri extends Fake implements Uri {}

class _FakeHttpHeaders extends Fake implements HttpHeaders {}

class _FakeHttpClientResponse extends Fake implements HttpClientResponse {}

class _FakeSocket extends Fake implements Socket {}

class _FakeStreamSubscription<T> extends Fake
    implements StreamSubscription<T> {}

/// A class which mocks [HttpClient].
///
/// See the documentation for Mockito's code generation for more information.
class MockHttpClient extends Mock implements HttpClient {
  MockHttpClient() {
    throwOnMissingStub(this);
  }

  @override
  Duration get idleTimeout =>
      super.noSuchMethod(Invocation.getter(#idleTimeout),
          returnValue: _FakeDuration()) as Duration;

  @override
  set idleTimeout(Duration? idleTimeout) =>
      super.noSuchMethod(Invocation.setter(#idleTimeout, idleTimeout));

  @override
  bool get autoUncompress =>
      super.noSuchMethod(Invocation.getter(#autoUncompress), returnValue: false)
          as bool;

  @override
  set autoUncompress(bool? autoUncompress) =>
      super.noSuchMethod(Invocation.setter(#autoUncompress, autoUncompress));

  @override
  Future<HttpClientRequest> open(
          String? method, String? host, int? port, String? path) =>
      super.noSuchMethod(
          Invocation.method(#open, <Object?>[method, host, port, path]),
          returnValue: Future<_FakeHttpClientRequest>.value(
              _FakeHttpClientRequest())) as Future<HttpClientRequest>;

  @override
  Future<HttpClientRequest> openUrl(String? method, Uri? url) =>
      super.noSuchMethod(Invocation.method(#openUrl, <Object?>[method, url]),
          returnValue: Future<_FakeHttpClientRequest>.value(
              _FakeHttpClientRequest())) as Future<HttpClientRequest>;

  @override
  Future<HttpClientRequest> get(String? host, int? port, String? path) =>
      super.noSuchMethod(Invocation.method(#get, <Object?>[host, port, path]),
          returnValue: Future<_FakeHttpClientRequest>.value(
              _FakeHttpClientRequest())) as Future<HttpClientRequest>;

  @override
  Future<HttpClientRequest> getUrl(Uri? url) => super.noSuchMethod(
          Invocation.method(#getUrl, <Object?>[url]),
          returnValue:
              Future<_FakeHttpClientRequest>.value(_FakeHttpClientRequest()))
      as Future<HttpClientRequest>;

  @override
  Future<HttpClientRequest> post(String? host, int? port, String? path) =>
      super.noSuchMethod(Invocation.method(#post, <Object?>[host, port, path]),
          returnValue: Future<_FakeHttpClientRequest>.value(
              _FakeHttpClientRequest())) as Future<HttpClientRequest>;

  @override
  Future<HttpClientRequest> postUrl(Uri? url) => super.noSuchMethod(
          Invocation.method(#postUrl, <Object?>[url]),
          returnValue:
              Future<_FakeHttpClientRequest>.value(_FakeHttpClientRequest()))
      as Future<HttpClientRequest>;

  @override
  Future<HttpClientRequest> put(String? host, int? port, String? path) =>
      super.noSuchMethod(Invocation.method(#put, <Object?>[host, port, path]),
          returnValue: Future<_FakeHttpClientRequest>.value(
              _FakeHttpClientRequest())) as Future<HttpClientRequest>;

  @override
  Future<HttpClientRequest> putUrl(Uri? url) => super.noSuchMethod(
          Invocation.method(#putUrl, <Object?>[url]),
          returnValue:
              Future<_FakeHttpClientRequest>.value(_FakeHttpClientRequest()))
      as Future<HttpClientRequest>;

  @override
  Future<HttpClientRequest> delete(String? host, int? port, String? path) =>
      super.noSuchMethod(
          Invocation.method(#delete, <Object?>[host, port, path]),
          returnValue: Future<_FakeHttpClientRequest>.value(
              _FakeHttpClientRequest())) as Future<HttpClientRequest>;

  @override
  Future<HttpClientRequest> deleteUrl(Uri? url) => super.noSuchMethod(
          Invocation.method(#deleteUrl, <Object?>[url]),
          returnValue:
              Future<_FakeHttpClientRequest>.value(_FakeHttpClientRequest()))
      as Future<HttpClientRequest>;

  @override
  Future<HttpClientRequest> patch(String? host, int? port, String? path) =>
      super.noSuchMethod(Invocation.method(#patch, <Object?>[host, port, path]),
          returnValue: Future<_FakeHttpClientRequest>.value(
              _FakeHttpClientRequest())) as Future<HttpClientRequest>;

  @override
  Future<HttpClientRequest> patchUrl(Uri? url) => super.noSuchMethod(
          Invocation.method(#patchUrl, <Object?>[url]),
          returnValue:
              Future<_FakeHttpClientRequest>.value(_FakeHttpClientRequest()))
      as Future<HttpClientRequest>;

  @override
  Future<HttpClientRequest> head(String? host, int? port, String? path) =>
      super.noSuchMethod(Invocation.method(#head, <Object?>[host, port, path]),
          returnValue: Future<_FakeHttpClientRequest>.value(
              _FakeHttpClientRequest())) as Future<HttpClientRequest>;

  @override
  Future<HttpClientRequest> headUrl(Uri? url) => super.noSuchMethod(
          Invocation.method(#headUrl, <Object?>[url]),
          returnValue:
              Future<_FakeHttpClientRequest>.value(_FakeHttpClientRequest()))
      as Future<HttpClientRequest>;

  @override
  void addCredentials(
          Uri? url, String? realm, HttpClientCredentials? credentials) =>
      super.noSuchMethod(Invocation.method(
          #addCredentials, <Object?>[url, realm, credentials]));

  @override
  void addProxyCredentials(String? host, int? port, String? realm,
          HttpClientCredentials? credentials) =>
      super.noSuchMethod(Invocation.method(
          #addProxyCredentials, <Object?>[host, port, realm, credentials]));

  @override
  void close({bool? force = false}) => super.noSuchMethod(
      Invocation.method(#close, <Object?>[], <Symbol, Object?>{#force: force}));
}

/// A class which mocks [HttpClientRequest].
///
/// See the documentation for Mockito's code generation for more information.
class MockHttpClientRequest extends Mock implements HttpClientRequest {
  MockHttpClientRequest() {
    throwOnMissingStub(this);
  }

  @override
  bool get persistentConnection =>
      super.noSuchMethod(Invocation.getter(#persistentConnection),
          returnValue: false) as bool;

  @override
  set persistentConnection(bool? persistentConnection) => super.noSuchMethod(
      Invocation.setter(#persistentConnection, persistentConnection));

  @override
  bool get followRedirects => super
          .noSuchMethod(Invocation.getter(#followRedirects), returnValue: false)
      as bool;

  @override
  set followRedirects(bool? followRedirects) =>
      super.noSuchMethod(Invocation.setter(#followRedirects, followRedirects));

  @override
  int get maxRedirects =>
      super.noSuchMethod(Invocation.getter(#maxRedirects), returnValue: 0)
          as int;

  @override
  set maxRedirects(int? maxRedirects) =>
      super.noSuchMethod(Invocation.setter(#maxRedirects, maxRedirects));

  @override
  int get contentLength =>
      super.noSuchMethod(Invocation.getter(#contentLength), returnValue: 0)
          as int;

  @override
  set contentLength(int? contentLength) =>
      super.noSuchMethod(Invocation.setter(#contentLength, contentLength));

  @override
  bool get bufferOutput =>
      super.noSuchMethod(Invocation.getter(#bufferOutput), returnValue: false)
          as bool;

  @override
  set bufferOutput(bool? bufferOutput) =>
      super.noSuchMethod(Invocation.setter(#bufferOutput, bufferOutput));

  @override
  String get method =>
      super.noSuchMethod(Invocation.getter(#method), returnValue: '') as String;

  @override
  Uri get uri =>
      super.noSuchMethod(Invocation.getter(#uri), returnValue: _FakeUri())
          as Uri;

  @override
  HttpHeaders get headers => super.noSuchMethod(Invocation.getter(#headers),
      returnValue: _FakeHttpHeaders()) as HttpHeaders;

  @override
  List<Cookie> get cookies =>
      super.noSuchMethod(Invocation.getter(#cookies), returnValue: <Cookie>[])
          as List<Cookie>;

  @override
  Future<HttpClientResponse> get done => super.noSuchMethod(
          Invocation.getter(#done),
          returnValue:
              Future<_FakeHttpClientResponse>.value(_FakeHttpClientResponse()))
      as Future<HttpClientResponse>;

  @override
  Future<HttpClientResponse> close() => super.noSuchMethod(
          Invocation.method(#close, <Object?>[]),
          returnValue:
              Future<_FakeHttpClientResponse>.value(_FakeHttpClientResponse()))
      as Future<HttpClientResponse>;
}

/// A class which mocks [HttpClientResponse].
///
/// See the documentation for Mockito's code generation for more information.
class MockHttpClientResponse extends Mock implements HttpClientResponse {
  MockHttpClientResponse() {
    throwOnMissingStub(this);
  }

  // Include an override method for the inherited listen method. This method
  // intercepts HttpClientResponse listen calls to return a mock image.
  @override
  StreamSubscription<List<int>> listen(void Function(List<int> event)? onData,
          {Function? onError, void Function()? onDone, bool? cancelOnError}) =>
      super.noSuchMethod(
          Invocation.method(
            #listen,
            <Object?>[onData],
            <Symbol, Object?>{
              #onError: onError,
              #onDone: onDone,
              #cancelOnError: cancelOnError
            },
          ),
          returnValue: _FakeStreamSubscription<List<int>>());

  @override
  int get statusCode =>
      super.noSuchMethod(Invocation.getter(#statusCode), returnValue: 0) as int;

  @override
  String get reasonPhrase =>
      super.noSuchMethod(Invocation.getter(#reasonPhrase), returnValue: '')
          as String;

  @override
  int get contentLength =>
      super.noSuchMethod(Invocation.getter(#contentLength), returnValue: 0)
          as int;

  @override
  HttpClientResponseCompressionState get compressionState =>
      super.noSuchMethod(Invocation.getter(#compressionState),
              returnValue: HttpClientResponseCompressionState.notCompressed)
          as HttpClientResponseCompressionState;

  @override
  bool get persistentConnection =>
      super.noSuchMethod(Invocation.getter(#persistentConnection),
          returnValue: false) as bool;

  @override
  bool get isRedirect =>
      super.noSuchMethod(Invocation.getter(#isRedirect), returnValue: false)
          as bool;

  @override
  List<RedirectInfo> get redirects =>
      super.noSuchMethod(Invocation.getter(#redirects),
          returnValue: <RedirectInfo>[]) as List<RedirectInfo>;

  @override
  HttpHeaders get headers => super.noSuchMethod(Invocation.getter(#headers),
      returnValue: _FakeHttpHeaders()) as HttpHeaders;

  @override
  List<Cookie> get cookies =>
      super.noSuchMethod(Invocation.getter(#cookies), returnValue: <Cookie>[])
          as List<Cookie>;

  @override
  Future<HttpClientResponse> redirect(
          [String? method, Uri? url, bool? followLoops]) =>
      super.noSuchMethod(
          Invocation.method(#redirect, <Object?>[method, url, followLoops]),
          returnValue: Future<_FakeHttpClientResponse>.value(
              _FakeHttpClientResponse())) as Future<HttpClientResponse>;

  @override
  Future<Socket> detachSocket() => super.noSuchMethod(
      Invocation.method(#detachSocket, <Object?>[]),
      returnValue: Future<_FakeSocket>.value(_FakeSocket())) as Future<Socket>;
}

/// A class which mocks [HttpHeaders].
///
/// See the documentation for Mockito's code generation for more information.
class MockHttpHeaders extends Mock implements HttpHeaders {
  MockHttpHeaders() {
    throwOnMissingStub(this);
  }

  @override
  int get contentLength =>
      super.noSuchMethod(Invocation.getter(#contentLength), returnValue: 0)
          as int;

  @override
  set contentLength(int? contentLength) =>
      super.noSuchMethod(Invocation.setter(#contentLength, contentLength));

  @override
  bool get persistentConnection =>
      super.noSuchMethod(Invocation.getter(#persistentConnection),
          returnValue: false) as bool;

  @override
  set persistentConnection(bool? persistentConnection) => super.noSuchMethod(
      Invocation.setter(#persistentConnection, persistentConnection));

  @override
  bool get chunkedTransferEncoding =>
      super.noSuchMethod(Invocation.getter(#chunkedTransferEncoding),
          returnValue: false) as bool;

  @override
  set chunkedTransferEncoding(bool? chunkedTransferEncoding) =>
      super.noSuchMethod(
          Invocation.setter(#chunkedTransferEncoding, chunkedTransferEncoding));

  @override
  List<String>? operator [](String? name) =>
      super.noSuchMethod(Invocation.method(#[], <Object?>[name]))
          as List<String>?;

  @override
  String? value(String? name) =>
      super.noSuchMethod(Invocation.method(#value, <Object?>[name])) as String?;

  @override
  void add(String? name, Object? value, {bool? preserveHeaderCase = false}) =>
      super.noSuchMethod(Invocation.method(#add, <Object?>[name, value],
          <Symbol, Object?>{#preserveHeaderCase: preserveHeaderCase}));

  @override
  void set(String? name, Object? value, {bool? preserveHeaderCase = false}) =>
      super.noSuchMethod(Invocation.method(#set, <Object?>[name, value],
          <Symbol, Object?>{#preserveHeaderCase: preserveHeaderCase}));

  @override
  void remove(String? name, Object? value) =>
      super.noSuchMethod(Invocation.method(#remove, <Object?>[name, value]));

  @override
  void removeAll(String? name) =>
      super.noSuchMethod(Invocation.method(#removeAll, <Object?>[name]));

  @override
  void forEach(void Function(String, List<String>)? action) =>
      super.noSuchMethod(Invocation.method(#forEach, <Object?>[action]));

  @override
  void noFolding(String? name) =>
      super.noSuchMethod(Invocation.method(#noFolding, <Object?>[name]));
}
