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

import 'package:litetest/litetest.dart';
import 'package:path/path.dart' as p;
import 'package:process_fakes/process_fakes.dart';
import 'package:skia_gold_client/skia_gold_client.dart';

void main() {
  /// A mock commit hash that is used to simulate a successful git call.
  const String mockCommitHash = '1234567890abcdef';

  /// Simulating what a presubmit environment would look like.
  const Map<String, String> presubmitEnv = <String, String>{
    'GOLDCTL': 'python tools/goldctl.py',
    'GOLD_TRYJOB': 'flutter/engine/1234567890',
    'LOGDOG_STREAM_PREFIX': 'buildbucket/cr-buildbucket.appspot.com/1234567890/+/logdog',
    'LUCI_CONTEXT': '{}',
  };

  /// Simulating what a postsubmit environment would look like.
  const Map<String, String> postsubmitEnv = <String, String>{
    'GOLDCTL': 'python tools/goldctl.py',
    'LOGDOG_STREAM_PREFIX': 'buildbucket/cr-buildbucket.appspot.com/1234567890/+/logdog',
    'LUCI_CONTEXT': '{}'
  };

  /// Simulating what a local environment would look like.
  const Map<String, String> localEnv = <String, String>{};

  /// Creates a [SkiaGoldClient] with the given [dimensions] and [verbose] flag.
  ///
  /// Optionally, the [onRun] function can be provided to handle the execution
  /// of the command-line tool. If not provided, it throws an
  /// [UnsupportedError] by default.
  ///
  /// Side-effects of the client can be observed through the test fixture.
  SkiaGoldClient createClient(
    _TestFixture fixture, {
    required Map<String, String> environment,
    Map<String, String>? dimensions,
    bool verbose = false,
    io.ProcessResult Function(List<String> command) onRun = _runUnhandled,
  }) {
    return SkiaGoldClient(
      fixture.workDirectory,
      dimensions: dimensions,
      httpClient: fixture.httpClient,
      processManager: FakeProcessManager(
        onRun: onRun,
      ),
      verbose: verbose,
      stderr: fixture.outputSink,
      environment: environment,
    );
  }

  /// Creates a `temp/auth_opt.json` file in the working directory.
  ///
  /// This simulates what the goldctl tool does when it runs.
  void createAuthOptDotJson(String workDirectory) {
    final io.File authOptDotJson = io.File(p.join(workDirectory, 'temp', 'auth_opt.json'));
    authOptDotJson.createSync(recursive: true);
    authOptDotJson.writeAsStringSync('{"GSUtil": false}');
  }

  test('fails if GOLDCTL is not set', () async {
    final _TestFixture fixture = _TestFixture();
    try {
      final SkiaGoldClient client = createClient(
        fixture,
        environment: localEnv,
      );
      try {
        await client.auth();
        fail('auth should fail if GOLDCTL is not set');
      } catch (error) {
        expect('$error', contains('GOLDCTL is not set'));
      }
    } finally {
      fixture.dispose();
    }
  });

  test('auth executes successfully', () async {
    final _TestFixture fixture = _TestFixture();
    try {
      final SkiaGoldClient client = createClient(
        fixture,
        environment: presubmitEnv,
        onRun: (List<String> command) {
          expect(command, <String>[
            'python tools/goldctl.py',
            'auth',
            '--work-dir',
            p.join(fixture.workDirectory.path, 'temp'),
            '--luci',
          ]);
          createAuthOptDotJson(fixture.workDirectory.path);
          return io.ProcessResult(0, 0, '', '');
        },
      );
      await client.auth();
    } finally {
      fixture.dispose();
    }
  });

  test('auth is only invoked once per instance', () async {
    final _TestFixture fixture = _TestFixture();
    try {
      int callsToGoldctl = 0;
      final SkiaGoldClient client = createClient(
        fixture,
        environment: presubmitEnv,
        onRun: (List<String> command) {
          callsToGoldctl++;
          expect(command, <String>[
            'python tools/goldctl.py',
            'auth',
            '--work-dir',
            p.join(fixture.workDirectory.path, 'temp'),
            '--luci',
          ]);
          createAuthOptDotJson(fixture.workDirectory.path);
          return io.ProcessResult(0, 0, '', '');
        },
      );

      await client.auth();
      await client.auth();
      expect(callsToGoldctl, 1);
    } finally {
      fixture.dispose();
    }
  });

  test('auth executes successfully with verbose logging', () async {
    final _TestFixture fixture = _TestFixture();
    try {
      final SkiaGoldClient client = createClient(
        fixture,
        environment: presubmitEnv,
        verbose: true,
        onRun: (List<String> command) {
          expect(command, <String>[
            'python tools/goldctl.py',
            'auth',
            '--verbose',
            '--work-dir',
            p.join(fixture.workDirectory.path, 'temp'),
            '--luci',
          ]);
          return io.ProcessResult(0, 0, 'stdout', 'stderr');
        },
      );

      await client.auth();
      expect(fixture.outputSink.toString(), contains('stdout:\nstdout'));
      expect(fixture.outputSink.toString(), contains('stderr:\nstderr'));
    } finally {
      fixture.dispose();
    }
  });

  test('auth fails', () async {
    final _TestFixture fixture = _TestFixture();
    try {
      final SkiaGoldClient client = createClient(
        fixture,
        environment: presubmitEnv,
        onRun: (List<String> command) {
          return io.ProcessResult(1, 0, '', 'error-text');
        },
      );

      try {
        await client.auth();
      } catch (error) {
        expect('$error', contains('Skia Gold authorization failed.'));
        expect('$error', contains('error-text'));
      }
    } finally {
      fixture.dispose();
    }
  });

  test('addImg [pre-submit] executes successfully', () async {
    final _TestFixture fixture = _TestFixture();
    try {
      final SkiaGoldClient client = createClient(
        fixture,
        environment: presubmitEnv,
        onRun: (List<String> command) {
          if (command case ['git', ...]) {
            return io.ProcessResult(0, 0, mockCommitHash, '');
          }
          if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
            return io.ProcessResult(0, 0, '', '');
          }
          expect(command, <String>[
            'python tools/goldctl.py',
            'imgtest',
            'add',
            '--work-dir',
            p.join(fixture.workDirectory.path, 'temp'),
            '--test-name',
            'test-name',
            '--png-file',
            p.join(fixture.workDirectory.path, 'temp', 'golden.png'),
            '--add-test-optional-key',
            'image_matching_algorithm:fuzzy',
            '--add-test-optional-key',
            'fuzzy_max_different_pixels:10',
            '--add-test-optional-key',
            'fuzzy_pixel_delta_threshold:0',
          ]);
          return io.ProcessResult(0, 0, '', '');
        },
      );

      await client.addImg(
        'test-name.foo',
        io.File(p.join(fixture.workDirectory.path, 'temp', 'golden.png')),
        screenshotSize: 1000,
      );
    } finally {
      fixture.dispose();
    }
  });

  test('addImg [pre-submit] executes successfully with verbose logging', () async {
    final _TestFixture fixture = _TestFixture();
    try {
      final SkiaGoldClient client = createClient(
        fixture,
        environment: presubmitEnv,
        verbose: true,
        onRun: (List<String> command) {
          if (command case ['git', ...]) {
            return io.ProcessResult(0, 0, mockCommitHash, '');
          }
          if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
            return io.ProcessResult(0, 0, '', '');
          }
          expect(command, <String>[
            'python tools/goldctl.py',
            'imgtest',
            'add',
            '--verbose',
            '--work-dir',
            p.join(fixture.workDirectory.path, 'temp'),
            '--test-name',
            'test-name',
            '--png-file',
            p.join(fixture.workDirectory.path, 'temp', 'golden.png'),
            '--add-test-optional-key',
            'image_matching_algorithm:fuzzy',
            '--add-test-optional-key',
            'fuzzy_max_different_pixels:10',
            '--add-test-optional-key',
            'fuzzy_pixel_delta_threshold:0',
          ]);
          return io.ProcessResult(0, 0, 'stdout', 'stderr');
        },
      );

      await client.addImg(
        'test-name.foo',
        io.File(p.join(fixture.workDirectory.path, 'temp', 'golden.png')),
        screenshotSize: 1000,
      );

      expect(fixture.outputSink.toString(), contains('stdout:\nstdout'));
      expect(fixture.outputSink.toString(), contains('stderr:\nstderr'));
    } finally {
      fixture.dispose();
    }
  });

  // A success case (exit code 0) with a message of "Untriaged" is OK.
  test('addImg [pre-submit] succeeds but has an untriaged image', () async {
    final _TestFixture fixture = _TestFixture();
    try {
      final SkiaGoldClient client = createClient(
        fixture,
        environment: presubmitEnv,
        onRun: (List<String> command) {
          if (command case ['git', ...]) {
            return io.ProcessResult(0, 0, mockCommitHash, '');
          }
          if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
            return io.ProcessResult(0, 0, '', '');
          }
          expect(command, <String>[
            'python tools/goldctl.py',
            'imgtest',
            'add',
            '--work-dir',
            p.join(fixture.workDirectory.path, 'temp'),
            '--test-name',
            'test-name',
            '--png-file',
            p.join(fixture.workDirectory.path, 'temp', 'golden.png'),
            '--add-test-optional-key',
            'image_matching_algorithm:fuzzy',
            '--add-test-optional-key',
            'fuzzy_max_different_pixels:10',
            '--add-test-optional-key',
            'fuzzy_pixel_delta_threshold:0',
          ]);
          // Intentionally returning a non-zero exit code.
          return io.ProcessResult(0, 1, 'Untriaged', '');
        },
      );

      await client.addImg(
        'test-name.foo',
        io.File(p.join(fixture.workDirectory.path, 'temp', 'golden.png')),
        screenshotSize: 1000,
      );
    } finally {
      fixture.dispose();
    }
  });

  test('addImg [pre-submit] fails due to an unexpected error', () async {
    final _TestFixture fixture = _TestFixture();
    try {
      final SkiaGoldClient client = createClient(
        fixture,
        environment: presubmitEnv,
        onRun: (List<String> command) {
          if (command case ['git', ...]) {
            return io.ProcessResult(0, 0, mockCommitHash, '');
          }
          if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
            return io.ProcessResult(0, 0, '', '');
          }
          return io.ProcessResult(1, 0, '', 'error-text');
        },
      );

      try {
        await client.addImg(
          'test-name.foo',
          io.File(p.join(fixture.workDirectory.path, 'temp', 'golden.png')),
          screenshotSize: 1000,
        );
      } catch (error) {
        expect('$error', contains('Skia Gold image test failed.'));
        expect('$error', contains('error-text'));
      }
    } finally {
      fixture.dispose();
    }
  });

  test('addImg [post-submit] executes successfully', () async {
    final _TestFixture fixture = _TestFixture();
    try {
      final SkiaGoldClient client = createClient(
        fixture,
        environment: postsubmitEnv,
        onRun: (List<String> command) {
          if (command case ['git', ...]) {
            return io.ProcessResult(0, 0, mockCommitHash, '');
          }
          if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
            return io.ProcessResult(0, 0, '', '');
          }
          expect(command, <String>[
            'python tools/goldctl.py',
            'imgtest',
            'add',
            '--work-dir',
            p.join(fixture.workDirectory.path, 'temp'),
            '--test-name',
            'test-name',
            '--png-file',
            p.join(fixture.workDirectory.path, 'temp', 'golden.png'),
            '--passfail',
            '--add-test-optional-key',
            'image_matching_algorithm:fuzzy',
            '--add-test-optional-key',
            'fuzzy_max_different_pixels:10',
            '--add-test-optional-key',
            'fuzzy_pixel_delta_threshold:0',
          ]);
          return io.ProcessResult(0, 0, '', '');
        },
      );

      await client.addImg(
        'test-name.foo',
        io.File(p.join(fixture.workDirectory.path, 'temp', 'golden.png')),
        screenshotSize: 1000,
      );
    } finally {
      fixture.dispose();
    }
  });

  test('addImg [post-submit] executes successfully with verbose logging', () async {
    final _TestFixture fixture = _TestFixture();
    try {
      final SkiaGoldClient client = createClient(
        fixture,
        environment: postsubmitEnv,
        verbose: true,
        onRun: (List<String> command) {
          if (command case ['git', ...]) {
            return io.ProcessResult(0, 0, mockCommitHash, '');
          }
          if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
            return io.ProcessResult(0, 0, '', '');
          }
          expect(command, <String>[
            'python tools/goldctl.py',
            'imgtest',
            'add',
            '--verbose',
            '--work-dir',
            p.join(fixture.workDirectory.path, 'temp'),
            '--test-name',
            'test-name',
            '--png-file',
            p.join(fixture.workDirectory.path, 'temp', 'golden.png'),
            '--passfail',
            '--add-test-optional-key',
            'image_matching_algorithm:fuzzy',
            '--add-test-optional-key',
            'fuzzy_max_different_pixels:10',
            '--add-test-optional-key',
            'fuzzy_pixel_delta_threshold:0',
          ]);
          return io.ProcessResult(0, 0, 'stdout', 'stderr');
        },
      );

      await client.addImg(
        'test-name.foo',
        io.File(p.join(fixture.workDirectory.path, 'temp', 'golden.png')),
        screenshotSize: 1000,
      );

      expect(fixture.outputSink.toString(), contains('stdout:\nstdout'));
      expect(fixture.outputSink.toString(), contains('stderr:\nstderr'));
    } finally {
      fixture.dispose();
    }
  });

  test('addImg [post-submit] fails due to an unapproved image', () async {
    final _TestFixture fixture = _TestFixture();
    try {
      final SkiaGoldClient client = createClient(
        fixture,
        environment: postsubmitEnv,
        onRun: (List<String> command) {
          if (command case ['git', ...]) {
            return io.ProcessResult(0, 0, mockCommitHash, '');
          }
          if (command case ['python tools/goldctl.py', 'imgtest', 'init', ...]) {
            return io.ProcessResult(0, 0, '', '');
          }
          return io.ProcessResult(1, 0, '', 'error-text');
        },
      );

      try {
        await client.addImg(
          'test-name.foo',
          io.File(p.join(fixture.workDirectory.path, 'temp', 'golden.png')),
          screenshotSize: 1000,
        );
      } catch (error) {
        expect('$error', contains('Skia Gold image test failed.'));
        expect('$error', contains('error-text'));
      }
    } finally {
      fixture.dispose();
    }
  });

  test('getExpectationsForTest returns the latest positive digest', () async {
    final _TestFixture fixture = _TestFixture();
    try {
      final SkiaGoldClient client = createClient(
        fixture,
        environment: presubmitEnv,
        onRun: (List<String> command) {
          expect(command, <String>[
            'python tools/goldctl.py',
            'imgtest',
            'get',
            '--work-dir',
            p.join(fixture.workDirectory.path, 'temp'),
            '--test-name',
            'test-name',
          ]);
          return io.ProcessResult(0, 0, '{"digest":"digest"}', '');
        },
      );

      final String hash = client.getTraceID('test-name');
      fixture.httpClient.setJsonResponse(
        Uri.parse('https://flutter-engine-gold.skia.org/json/v2/latestpositivedigest/$hash'),
        <String, Object?>{
          'digest': 'digest',
        },
      );

      final String? digest = await client.getExpectationForTest('test-name');
      expect(digest, 'digest');
    } finally {
      fixture.dispose();
    }
  });
}

final class _TestFixture {
  _TestFixture();

  final io.Directory workDirectory = io.Directory.systemTemp.createTempSync('skia_gold_client_test');
  final _FakeHttpClient httpClient = _FakeHttpClient();
  final StringSink outputSink = StringBuffer();

  void dispose() {
    workDirectory.deleteSync(recursive: true);
  }
}

io.ProcessResult _runUnhandled(List<String> command) {
  throw UnimplementedError('Unhandled run: ${command.join(' ')}');
}

/// An  in-memory fake of [io.HttpClient] that allows [getUrl] to be mocked.
///
/// This class is used to simulate a response from the server.
///
/// Any other methods called on this class will throw a [NoSuchMethodError].
final class _FakeHttpClient implements io.HttpClient {
  final Map<Uri, Object?> _expectedResponses = <Uri, Object?>{};

  /// Sets an expected response for the given [request] to [jsonEncodableValue].
  ///
  /// This method is used to simulate a response from the server.
  void setJsonResponse(Uri request, Object? jsonEncodableValue) {
    _expectedResponses[request] = jsonEncodableValue;
  }

  @override
  Future<io.HttpClientRequest> getUrl(Uri url) async {
    final Object? response = _expectedResponses[url];
    if (response == null) {
      throw StateError('No request expected for $url');
    }
    return _FakeHttpClientRequest.withJsonResponse(response);
  }

  @override
  Object? noSuchMethod(Invocation invocation) {
    return super.noSuchMethod(invocation);
  }
}

final class _FakeHttpClientRequest implements io.HttpClientRequest {
  factory _FakeHttpClientRequest.withJsonResponse(Object? jsonResponse) {
    final Uint8List bytes = utf8.encoder.convert(jsonEncode(jsonResponse));
    return _FakeHttpClientRequest._(_FakeHttpClientResponse(bytes));
  }

  _FakeHttpClientRequest._(this._response);

  final io.HttpClientResponse _response;

  @override
  Future<io.HttpClientResponse> close() async {
    return _response;
  }

  @override
  Object? noSuchMethod(Invocation invocation) {
    return super.noSuchMethod(invocation);
  }
}

final class _FakeHttpClientResponse extends Stream<List<int>>
    implements io.HttpClientResponse {
  _FakeHttpClientResponse(this._bytes);

  final Uint8List _bytes;

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

  @override
  int get statusCode => 200;

  @override
  Object? noSuchMethod(Invocation invocation) {
    return super.noSuchMethod(invocation);
  }
}
