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

// See also dev/automated_tests/flutter_test/flutter_gold_test.dart

import 'dart:convert';
import 'dart:ffi' show Abi;
import 'dart:io' hide Directory;

import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter_goldens/flutter_goldens.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:platform/platform.dart';
import 'package:process/process.dart';

import 'json_templates.dart';

// TODO(ianh): make sure all constructors order their arguments in a manner consistent with the defined parameter order

const String _kFlutterRoot = '/flutter';

// 1x1 transparent pixel
const List<int> _kTestPngBytes = <int>[
  137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0,
  1, 0, 0, 0, 1, 8, 6, 0, 0, 0, 31, 21, 196, 137, 0, 0, 0, 11, 73, 68, 65, 84,
  120, 1, 99, 97, 0, 2, 0, 0, 25, 0, 5, 144, 240, 54, 245, 0, 0, 0, 0, 73, 69,
  78, 68, 174, 66, 96, 130,
];

void main() {
  group('SkiaGoldClient', () {
    test('web HTML test', () async {
      final MemoryFileSystem fs = MemoryFileSystem();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{
          'GOLDCTL': 'goldctl',
          'FLUTTER_ROOT': _kFlutterRoot,
          'FLUTTER_TEST_BROWSER': 'Chrome',
          'FLUTTER_WEB_RENDERER': 'html',
        },
        operatingSystem: 'macos'
      );
      final FakeProcessManager process = FakeProcessManager();
      final FakeHttpClient fakeHttpClient = FakeHttpClient();
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      final SkiaGoldClient skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
        log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
      );

      final File goldenFile = fs.file('/workDirectory/temp/golden_file_test.png')
        ..createSync(recursive: true);

      const RunInvocation goldctlInvocation = RunInvocation(
        <String>[
          'goldctl',
          'imgtest', 'add',
          '--work-dir', '/workDirectory/temp',
          '--test-name', 'golden_file_test',
          '--png-file', '/workDirectory/temp/golden_file_test.png',
          '--passfail',
          '--add-test-optional-key', 'image_matching_algorithm:fuzzy',
          '--add-test-optional-key', 'fuzzy_max_different_pixels:20',
          '--add-test-optional-key', 'fuzzy_pixel_delta_threshold:4',
        ],
        null,
      );
      process.processResults[goldctlInvocation] = ProcessResult(123, 0, '', '');

      expect(
        await skiaClient.imgtestAdd('golden_file_test.png', goldenFile),
        isTrue,
      );
    });

    test('web CanvasKit test', () async {
      final MemoryFileSystem fs = MemoryFileSystem();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{
          'GOLDCTL': 'goldctl',
          'FLUTTER_ROOT': _kFlutterRoot,
          'FLUTTER_TEST_BROWSER': 'Chrome',
          'FLUTTER_WEB_RENDERER': 'canvaskit',
        },
        operatingSystem: 'macos'
      );
      final FakeProcessManager process = FakeProcessManager();
      final FakeHttpClient fakeHttpClient = FakeHttpClient();
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      final SkiaGoldClient skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
        log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
      );

      final File goldenFile = fs.file('/workDirectory/temp/golden_file_test.png')
        ..createSync(recursive: true);

      const RunInvocation goldctlInvocation = RunInvocation(
        <String>[
          'goldctl',
          'imgtest', 'add',
          '--work-dir', '/workDirectory/temp',
          '--test-name', 'golden_file_test',
          '--png-file', '/workDirectory/temp/golden_file_test.png',
          '--passfail',
        ],
        null,
      );
      process.processResults[goldctlInvocation] = ProcessResult(123, 0, '', '');

      expect(
        await skiaClient.imgtestAdd('golden_file_test.png', goldenFile),
        isTrue,
      );
    });

    test('auth performs minimal work if already authorized', () async {
      final MemoryFileSystem fs = MemoryFileSystem();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
        operatingSystem: 'macos'
      );
      final FakeProcessManager process = FakeProcessManager();
      final FakeHttpClient fakeHttpClient = FakeHttpClient();
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      final SkiaGoldClient skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
        log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
      );
      final File authFile = fs.file('/workDirectory/temp/auth_opt.json')
        ..createSync(recursive: true);
      authFile.writeAsStringSync(authTemplate());
      process.fallbackProcessResult = ProcessResult(123, 0, '', '');
      await skiaClient.auth();

      expect(process.workingDirectories, isEmpty);
    });

    test('gsutil is checked when authorization file is present', () async {
      final MemoryFileSystem fs = MemoryFileSystem();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
        operatingSystem: 'macos'
      );
      final FakeProcessManager process = FakeProcessManager();
      final FakeHttpClient fakeHttpClient = FakeHttpClient();
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      final SkiaGoldClient skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
        log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
      );
      final File authFile = fs.file('/workDirectory/temp/auth_opt.json')
        ..createSync(recursive: true);
      authFile.writeAsStringSync(authTemplate(gsutil: true));
      expect(
        await skiaClient.clientIsAuthorized(),
        isFalse,
      );
    });

    test('throws for error state from auth', () async {
      final MemoryFileSystem fs = MemoryFileSystem();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{
          'FLUTTER_ROOT': _kFlutterRoot,
          'GOLD_SERVICE_ACCOUNT' : 'Service Account',
          'GOLDCTL' : 'goldctl',
        },
        operatingSystem: 'macos'
      );
      final FakeProcessManager process = FakeProcessManager();
      final FakeHttpClient fakeHttpClient = FakeHttpClient();
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      final SkiaGoldClient skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
        log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
      );

      process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');

      expect(
        skiaClient.auth(),
        throwsException,
      );
    });

    test('throws for error state from init', () {
      final MemoryFileSystem fs = MemoryFileSystem();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{
          'FLUTTER_ROOT': _kFlutterRoot,
          'GOLDCTL' : 'goldctl',
        },
        operatingSystem: 'macos'
      );
      final FakeProcessManager process = FakeProcessManager();
      final FakeHttpClient fakeHttpClient = FakeHttpClient();
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      final SkiaGoldClient skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
        log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
      );

      const RunInvocation gitInvocation = RunInvocation(
        <String>['git', 'rev-parse', 'HEAD'],
        '/flutter',
      );
      const RunInvocation goldctlInvocation = RunInvocation(
        <String>[
          'goldctl',
          'imgtest', 'init',
          '--instance', 'flutter',
          '--work-dir', '/workDirectory/temp',
          '--commit', '12345678',
          '--keys-file', '/workDirectory/keys.json',
          '--failure-file', '/workDirectory/failures.json',
          '--passfail',
        ],
        null,
      );
      process.processResults[gitInvocation] = ProcessResult(12345678, 0, '12345678', '');
      process.processResults[goldctlInvocation] = ProcessResult(123, 1, 'Expected failure', 'Expected failure');
      process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');

      expect(
        skiaClient.imgtestInit(),
        throwsException,
      );
    });

    test('Only calls init once', () async {
      final MemoryFileSystem fs = MemoryFileSystem();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{
          'FLUTTER_ROOT': _kFlutterRoot,
          'GOLDCTL' : 'goldctl',
        },
        operatingSystem: 'macos'
      );
      final FakeProcessManager process = FakeProcessManager();
      final FakeHttpClient fakeHttpClient = FakeHttpClient();
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      final SkiaGoldClient skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
        log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
      );

      const RunInvocation gitInvocation = RunInvocation(
        <String>['git', 'rev-parse', 'HEAD'],
        '/flutter',
      );
      const RunInvocation goldctlInvocation = RunInvocation(
        <String>[
          'goldctl',
          'imgtest', 'init',
          '--instance', 'flutter',
          '--work-dir', '/workDirectory/temp',
          '--commit', '1234',
          '--keys-file', '/workDirectory/keys.json',
          '--failure-file', '/workDirectory/failures.json',
          '--passfail',
        ],
        null,
      );
      process.processResults[gitInvocation] = ProcessResult(1234, 0, '1234', '');
      process.processResults[goldctlInvocation] = ProcessResult(5678, 0, '5678', '');
      process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');

      // First call
      await skiaClient.imgtestInit();

      // Remove fake process result.
      // If the init call is executed again, the fallback process will throw.
      process.processResults.remove(goldctlInvocation);

      // Second call
      await skiaClient.imgtestInit();
    });

    test('Only calls tryjob init once', () async {
      final MemoryFileSystem fs = MemoryFileSystem();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{
          'FLUTTER_ROOT': _kFlutterRoot,
          'GOLDCTL' : 'goldctl',
          'SWARMING_TASK_ID' : '4ae997b50dfd4d11',
          'LOGDOG_STREAM_PREFIX' : 'buildbucket/cr-buildbucket.appspot.com/8885996262141582672',
          'GOLD_TRYJOB' : 'refs/pull/49815/head',
        },
        operatingSystem: 'macos'
      );
      final FakeProcessManager process = FakeProcessManager();
      final FakeHttpClient fakeHttpClient = FakeHttpClient();
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      final SkiaGoldClient skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
        log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
      );

      const RunInvocation gitInvocation = RunInvocation(
        <String>['git', 'rev-parse', 'HEAD'],
        '/flutter',
      );
      const RunInvocation goldctlInvocation = RunInvocation(
        <String>[
          'goldctl',
          'imgtest', 'init',
          '--instance', 'flutter',
          '--work-dir', '/workDirectory/temp',
          '--commit', '1234',
          '--keys-file', '/workDirectory/keys.json',
          '--failure-file', '/workDirectory/failures.json',
          '--passfail',
          '--crs', 'github',
          '--patchset_id', '1234',
          '--changelist', '49815',
          '--cis', 'buildbucket',
          '--jobid', '8885996262141582672',
        ],
        null,
      );
      process.processResults[gitInvocation] = ProcessResult(1234, 0, '1234', '');
      process.processResults[goldctlInvocation] = ProcessResult(5678, 0, '5678', '');
      process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');

      // First call
      await skiaClient.tryjobInit();

      // Remove fake process result.
      // If the init call is executed again, the fallback process will throw.
      process.processResults.remove(goldctlInvocation);

      // Second call
      await skiaClient.tryjobInit();
    });

    test('throws for error state from imgtestAdd', () {
      final MemoryFileSystem fs = MemoryFileSystem();
      final File goldenFile = fs.file('/workDirectory/temp/golden_file_test.png')
        ..createSync(recursive: true);
      final FakePlatform platform = FakePlatform(
          environment: <String, String>{
            'FLUTTER_ROOT': _kFlutterRoot,
            'GOLDCTL' : 'goldctl',
          },
          operatingSystem: 'macos'
      );
      final FakeProcessManager process = FakeProcessManager();
      final FakeHttpClient fakeHttpClient = FakeHttpClient();
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      final SkiaGoldClient skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
        log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
      );
      const RunInvocation goldctlInvocation = RunInvocation(
        <String>[
          'goldctl',
          'imgtest', 'add',
          '--work-dir', '/workDirectory/temp',
          '--test-name', 'golden_file_test',
          '--png-file', '/workDirectory/temp/golden_file_test.png',
          '--passfail',
        ],
        null,
      );
      process.processResults[goldctlInvocation] = ProcessResult(123, 1, 'Expected failure', 'Expected failure');
      process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');

      expect(
        skiaClient.imgtestAdd('golden_file_test', goldenFile),
        throwsException,
      );
    });

    test('correctly inits tryjob for luci', () async {
      final MemoryFileSystem fs = MemoryFileSystem();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{
          'FLUTTER_ROOT': _kFlutterRoot,
          'GOLDCTL' : 'goldctl',
          'SWARMING_TASK_ID' : '4ae997b50dfd4d11',
          'LOGDOG_STREAM_PREFIX' : 'buildbucket/cr-buildbucket.appspot.com/8885996262141582672',
          'GOLD_TRYJOB' : 'refs/pull/49815/head',
        },
        operatingSystem: 'macos'
      );
      final FakeProcessManager process = FakeProcessManager();
      final FakeHttpClient fakeHttpClient = FakeHttpClient();
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      final SkiaGoldClient skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
        log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
      );

      final List<String> ciArguments = skiaClient.getCIArguments();

      expect(
        ciArguments,
        equals(
          <String>[
            '--changelist', '49815',
            '--cis', 'buildbucket',
            '--jobid', '8885996262141582672',
          ],
        ),
      );
    });

     test('Creates traceID correctly', () async {
       final MemoryFileSystem fs = MemoryFileSystem();
       final FakePlatform platform = FakePlatform(
         environment: <String, String>{
           'FLUTTER_ROOT': _kFlutterRoot,
           'GOLDCTL' : 'goldctl',
           'SWARMING_TASK_ID' : '4ae997b50dfd4d11',
           'LOGDOG_STREAM_PREFIX' : 'buildbucket/cr-buildbucket.appspot.com/8885996262141582672',
           'GOLD_TRYJOB' : 'refs/pull/49815/head',
         },
         operatingSystem: 'linux'
       );
       final FakeProcessManager process = FakeProcessManager();
       final FakeHttpClient fakeHttpClient = FakeHttpClient();
       fs.directory(_kFlutterRoot).createSync(recursive: true);
       final Directory workDirectory = fs.directory('/workDirectory')
         ..createSync(recursive: true);
       final SkiaGoldClient skiaClient = SkiaGoldClient(
         workDirectory,
         fs: fs,
         process: process,
         platform: platform,
         httpClient: fakeHttpClient,
         abi: Abi.linuxX64,
         log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
       );

       expect(
         skiaClient.getTraceID('flutter.golden.1'),
         equals('1937c1c93610cc0122a86a83d5bd38a4'),
       );
     });

     test('Creates traceID correctly - Browser', () async {
       final MemoryFileSystem fs = MemoryFileSystem();
       final FakePlatform platform = FakePlatform(
         environment: <String, String>{
           'FLUTTER_ROOT': _kFlutterRoot,
           'GOLDCTL' : 'goldctl',
           'SWARMING_TASK_ID' : '4ae997b50dfd4d11',
           'LOGDOG_STREAM_PREFIX' : 'buildbucket/cr-buildbucket.appspot.com/8885996262141582672',
           'GOLD_TRYJOB' : 'refs/pull/49815/head',
           'FLUTTER_TEST_BROWSER' : 'chrome',
         },
         operatingSystem: 'linux'
       );
       final FakeProcessManager process = FakeProcessManager();
       final FakeHttpClient fakeHttpClient = FakeHttpClient();
       fs.directory(_kFlutterRoot).createSync(recursive: true);
       final Directory workDirectory = fs.directory('/workDirectory')
         ..createSync(recursive: true);
       final SkiaGoldClient skiaClient = SkiaGoldClient(
         workDirectory,
         fs: fs,
         process: process,
         platform: platform,
         httpClient: fakeHttpClient,
         abi: Abi.linuxX64,
         log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
       );

       expect(
         skiaClient.getTraceID('flutter.golden.1'),
         equals('bc44a50c01eb3bbaf72a80d76c1c2305'),
       );
     });

    test('Creates traceID correctly - locally - should defer to luci traceID', () async {
      final MemoryFileSystem fs = MemoryFileSystem();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{
          'FLUTTER_ROOT': _kFlutterRoot,
        },
        operatingSystem: 'macos'
      );
      final FakeProcessManager process = FakeProcessManager();
      final FakeHttpClient fakeHttpClient = FakeHttpClient();
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      final SkiaGoldClient skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
        abi: Abi.linuxX64,
        log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
      );
      expect(
        skiaClient.getTraceID('flutter.golden.1'),
        equals('8821f4896801fcdd7cd6d30f5a8e4284'),
      );
    });

    test('throws for error state from imgtestAdd', () {
      final MemoryFileSystem fs = MemoryFileSystem();
      final File goldenFile = fs.file('/workDirectory/temp/golden_file_test.png')
        ..createSync(recursive: true);
      final FakePlatform platform = FakePlatform(
          environment: <String, String>{
            'FLUTTER_ROOT': _kFlutterRoot,
            'GOLDCTL' : 'goldctl',
          },
          operatingSystem: 'macos'
      );
      final FakeProcessManager process = FakeProcessManager();
      final FakeHttpClient fakeHttpClient = FakeHttpClient();
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      final SkiaGoldClient skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
        log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
      );
      const RunInvocation goldctlInvocation = RunInvocation(
        <String>[
          'goldctl',
          'imgtest', 'add',
          '--work-dir', '/workDirectory/temp',
          '--test-name', 'golden_file_test',
          '--png-file', '/workDirectory/temp/golden_file_test.png',
          '--passfail',
        ],
        null,
      );
      process.processResults[goldctlInvocation] = ProcessResult(123, 1, 'Expected failure', 'Expected failure');
      process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');

      expect(
          skiaClient.imgtestAdd('golden_file_test', goldenFile),
        throwsA(
          isA<SkiaException>().having((SkiaException error) => error.message,
            'message',
            contains('result-state.json'),
          ),
        ),
      );
    });

    test('throws for error state from tryjobAdd', () {
      final MemoryFileSystem fs = MemoryFileSystem();
      final File goldenFile = fs.file('/workDirectory/temp/golden_file_test.png')
        ..createSync(recursive: true);
      final FakePlatform platform = FakePlatform(
          environment: <String, String>{
            'FLUTTER_ROOT': _kFlutterRoot,
            'GOLDCTL' : 'goldctl',
          },
          operatingSystem: 'macos'
      );
      final FakeProcessManager process = FakeProcessManager();
      final FakeHttpClient fakeHttpClient = FakeHttpClient();
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      final SkiaGoldClient skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
        log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
      );
      const RunInvocation goldctlInvocation = RunInvocation(
        <String>[
          'goldctl',
          'imgtest', 'add',
          '--work-dir', '/workDirectory/temp',
          '--test-name', 'golden_file_test',
          '--png-file', '/workDirectory/temp/golden_file_test.png',
          '--passfail',
        ],
        null,
      );
      process.processResults[goldctlInvocation] = ProcessResult(123, 1, 'Expected failure', 'Expected failure');
      process.fallbackProcessResult = ProcessResult(123, 1, 'Fallback failure', 'Fallback failure');
      expect(
        skiaClient.tryjobAdd('golden_file_test', goldenFile),
        throwsA(
          isA<SkiaException>().having((SkiaException error) => error.message,
            'message',
            contains('result-state.json'),
          ),
        ),
      );
    });

    group('Request Handling', () {
      test('image bytes are processed properly', () async {
        const String expectation = '55109a4bed52acc780530f7a9aeff6c0';
        final MemoryFileSystem fs = MemoryFileSystem();
        final FakePlatform platform = FakePlatform(
          environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
          operatingSystem: 'macos'
        );
        final FakeProcessManager process = FakeProcessManager();
        final FakeHttpClient fakeHttpClient = FakeHttpClient();
        fs.directory(_kFlutterRoot).createSync(recursive: true);
        final Directory workDirectory = fs.directory('/workDirectory')
          ..createSync(recursive: true);
        final SkiaGoldClient skiaClient = SkiaGoldClient(
          workDirectory,
          fs: fs,
          process: process,
          platform: platform,
          httpClient: fakeHttpClient,
          log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
        );
        final Uri imageUrl = Uri.parse(
          'https://flutter-gold.skia.org/img/images/$expectation.png'
        );
        final FakeHttpClientRequest fakeImageRequest = FakeHttpClientRequest();
        final FakeHttpImageResponse fakeImageResponse = FakeHttpImageResponse(
          imageResponseTemplate()
        );

        fakeHttpClient.request = fakeImageRequest;
        fakeImageRequest.response = fakeImageResponse;

        final List<int> masterBytes = await skiaClient.getImageBytes(expectation);

        expect(fakeHttpClient.lastUri, imageUrl);
        expect(masterBytes, equals(_kTestPngBytes));
      });
    });
  });

  group('FlutterGoldenFileComparator', () {
    test('calculates the basedir correctly from defaultComparator for local testing', () async {
      final MemoryFileSystem fs = MemoryFileSystem();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
        operatingSystem: 'macos'
      );
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final FakeLocalFileComparator defaultComparator = FakeLocalFileComparator();
      final Directory flutterRoot = fs.directory(platform.environment['FLUTTER_ROOT'])
        ..createSync(recursive: true);
      defaultComparator.basedir = flutterRoot.childDirectory('baz').uri;
      final Directory basedir = FlutterGoldenFileComparator.getBaseDirectory(
        defaultComparator,
        platform,
        fs: fs,
      );
      expect(
        basedir.uri,
        fs.directory('/flutter/bin/cache/pkg/skia_goldens/baz').uri,
      );
    });

    test('ignores version number', () {
      final List<String> log = <String>[];
      final MemoryFileSystem fs = MemoryFileSystem();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
        operatingSystem: 'macos'
      );
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      final Directory basedir = fs.directory('flutter/test/library/')
        ..createSync(recursive: true);
      final FlutterGoldenFileComparator comparator = FlutterPostSubmitFileComparator(
        basedir.uri,
        FakeSkiaGoldClient(),
        fs: fs,
        platform: platform,
        log: log.add,
      );
      final Uri key = comparator.getTestUri(Uri.parse('foo.png'), 1);
      expect(key, Uri.parse('foo.png'));
      expect(log, isEmpty);
    });

    test('adds namePrefix', () async {
      final List<String> log = <String>[];
      final MemoryFileSystem fs = MemoryFileSystem();
      final FakePlatform platform = FakePlatform(
        environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
        operatingSystem: 'macos'
      );
      fs.directory(_kFlutterRoot).createSync(recursive: true);
      const String libraryName = 'sidedishes';
      const String namePrefix = 'tomatosalad';
      const String fileName = 'lettuce.png';
      final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
      final Directory basedir = fs.directory('flutter/test/$libraryName/')
        ..createSync(recursive: true);
      final FlutterGoldenFileComparator comparator = FlutterPostSubmitFileComparator(
        basedir.uri,
        fakeSkiaClient,
        fs: fs,
        platform: platform,
        namePrefix: namePrefix,
        log: log.add,
      );
      await comparator.compare(
        Uint8List.fromList(_kTestPngBytes),
        Uri.parse(fileName),
      );
      expect(fakeSkiaClient.testNames.single, '$namePrefix.$libraryName.$fileName');
      expect(log, isEmpty);
    });

    group('Post-Submit', () {
      test('asserts .png format', () async {
        final List<String> log = <String>[];
        final MemoryFileSystem fs = MemoryFileSystem();
        final FakePlatform platform = FakePlatform(
          environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
          operatingSystem: 'macos'
        );
        fs.directory(_kFlutterRoot).createSync(recursive: true);
        final Directory basedir = fs.directory('flutter/test/library/')
          ..createSync(recursive: true);
        final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
        final FlutterGoldenFileComparator comparator = FlutterPostSubmitFileComparator(
          basedir.uri,
          fakeSkiaClient,
          fs: fs,
          platform: platform,
          log: log.add,
        );
        await expectLater(
          () async {
            return comparator.compare(
              Uint8List.fromList(_kTestPngBytes),
              Uri.parse('flutter.golden_test.1'),
            );
          },
          throwsA(
            isA<AssertionError>().having((AssertionError error) => error.toString(),
              'description',
              contains(
                'Golden files in the Flutter framework must end with the file '
                'extension .png.'
              ),
            ),
          ),
        );
        expect(log, isEmpty);
      });

      test('calls init during compare', () {
        final List<String> log = <String>[];
        final MemoryFileSystem fs = MemoryFileSystem();
        final FakePlatform platform = FakePlatform(
          environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
          operatingSystem: 'macos'
        );
        fs.directory(_kFlutterRoot).createSync(recursive: true);
        final Directory basedir = fs.directory('flutter/test/library/')
          ..createSync(recursive: true);
        final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
        final FlutterGoldenFileComparator comparator = FlutterPostSubmitFileComparator(
          basedir.uri,
          fakeSkiaClient,
          fs: fs,
          platform: platform,
          log: log.add,
        );
        expect(fakeSkiaClient.initCalls, 0);
        comparator.compare(
          Uint8List.fromList(_kTestPngBytes),
          Uri.parse('flutter.golden_test.1.png'),
        );
        expect(fakeSkiaClient.initCalls, 1);
        expect(log, isEmpty);
      });

      test('does not call init in during construction', () {
        final MemoryFileSystem fs = MemoryFileSystem();
        final FakePlatform platform = FakePlatform(
          environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
          operatingSystem: 'macos'
        );
        fs.directory(_kFlutterRoot).createSync(recursive: true);
        final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
        expect(fakeSkiaClient.initCalls, 0);
        FlutterPostSubmitFileComparator.fromDefaultComparator(
          platform,
          goldens: fakeSkiaClient,
          log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
          fs: fs,
        );
        expect(fakeSkiaClient.initCalls, 0);
      });
    });

    group('Pre-Submit', () {
      test('asserts .png format', () async {
        final List<String> log = <String>[];
        final MemoryFileSystem fs = MemoryFileSystem();
        final FakePlatform platform = FakePlatform(
          environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
          operatingSystem: 'macos'
        );
        fs.directory(_kFlutterRoot).createSync(recursive: true);
        final Directory basedir = fs.directory('flutter/test/library/')
          ..createSync(recursive: true);
        final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
        final FlutterGoldenFileComparator comparator = FlutterPreSubmitFileComparator(
          basedir.uri,
          fakeSkiaClient,
          fs: fs,
          platform: platform,
          log: log.add,
        );
        await expectLater(
          () async {
            return comparator.compare(
              Uint8List.fromList(_kTestPngBytes),
              Uri.parse('flutter.golden_test.1'),
            );
          },
          throwsA(
            isA<AssertionError>().having((AssertionError error) => error.toString(),
              'description',
              contains(
                'Golden files in the Flutter framework must end with the file '
                'extension .png.'
              ),
            ),
          ),
        );
        expect(log, isEmpty);
      });

      test('calls init during compare', () {
        final List<String> log = <String>[];
        final MemoryFileSystem fs = MemoryFileSystem();
        final FakePlatform platform = FakePlatform(
          environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
          operatingSystem: 'macos'
        );
        fs.directory(_kFlutterRoot).createSync(recursive: true);
        final Directory basedir = fs.directory('flutter/test/library/')
          ..createSync(recursive: true);
        final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
        final FlutterGoldenFileComparator comparator = FlutterPreSubmitFileComparator(
          basedir.uri,
          fakeSkiaClient,
          fs: fs,
          platform: platform,
          log: log.add,
        );
        expect(fakeSkiaClient.tryInitCalls, 0);
        comparator.compare(
          Uint8List.fromList(_kTestPngBytes),
          Uri.parse('flutter.golden_test.1.png'),
        );
        expect(fakeSkiaClient.tryInitCalls, 1);
        expect(log, isEmpty);
      });

      test('does not call init in during construction', () {
        final MemoryFileSystem fs = MemoryFileSystem();
        final FakePlatform platform = FakePlatform(
          environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
          operatingSystem: 'macos'
        );
        fs.directory(_kFlutterRoot).createSync(recursive: true);
        final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
        expect(fakeSkiaClient.tryInitCalls, 0);
        FlutterPostSubmitFileComparator.fromDefaultComparator(
          platform,
          goldens: fakeSkiaClient,
          log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
          fs: fs,
        );
        expect(fakeSkiaClient.tryInitCalls, 0);
      });
    });

    group('Local', () {
      test('asserts .png format', () async {
        final List<String> log = <String>[];
        final MemoryFileSystem fs = MemoryFileSystem();
        fs.directory(_kFlutterRoot).createSync(recursive: true);
        final Directory basedir = fs.directory('flutter/test/library/')
          ..createSync(recursive: true);
        final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
        final FlutterGoldenFileComparator comparator = FlutterLocalFileComparator(
          basedir.uri,
          fakeSkiaClient,
          fs: fs,
          platform: FakePlatform(
            environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
            operatingSystem: 'macos',
          ),
          log: log.add,
        );
        const String hash = '55109a4bed52acc780530f7a9aeff6c0';
        fakeSkiaClient.expectationForTestValues['flutter.golden_test.1'] = hash;
        fakeSkiaClient.imageBytesValues[hash] =_kTestPngBytes;
        fakeSkiaClient.cleanTestNameValues['library.flutter.golden_test.1.png'] = 'flutter.golden_test.1';
        await expectLater(
          () async {
            return comparator.compare(
              Uint8List.fromList(_kTestPngBytes),
              Uri.parse('flutter.golden_test.1'),
            );
          },
          throwsA(
            isA<AssertionError>().having((AssertionError error) => error.toString(),
              'description',
              contains(
                'Golden files in the Flutter framework must end with the file '
                'extension .png.'
              ),
            ),
          ),
        );
        expect(log, isEmpty);
      });

      test('passes when bytes match', () async {
        final List<String> log = <String>[];
        final MemoryFileSystem fs = MemoryFileSystem();
        fs.directory(_kFlutterRoot).createSync(recursive: true);
        final Directory basedir = fs.directory('flutter/test/library/')
          ..createSync(recursive: true);
        final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();
        final FlutterGoldenFileComparator comparator = FlutterLocalFileComparator(
          basedir.uri,
          fakeSkiaClient,
          fs: fs,
          platform: FakePlatform(
            environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
            operatingSystem: 'macos',
          ),
          log: log.add,
        );
        const String hash = '55109a4bed52acc780530f7a9aeff6c0';
        fakeSkiaClient.expectationForTestValues['flutter.golden_test.1'] = hash;
        fakeSkiaClient.imageBytesValues[hash] =_kTestPngBytes;
        fakeSkiaClient.cleanTestNameValues['library.flutter.golden_test.1.png'] = 'flutter.golden_test.1';
        expect(
          await comparator.compare(
            Uint8List.fromList(_kTestPngBytes),
            Uri.parse('flutter.golden_test.1.png'),
          ),
          isTrue,
        );
        expect(log, isEmpty);
      });

      test('returns FlutterSkippingGoldenFileComparator when network connection is unavailable', () async {
        final MemoryFileSystem fs = MemoryFileSystem();
        final FakePlatform platform = FakePlatform(
          environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
          operatingSystem: 'macos'
        );
        fs.directory(_kFlutterRoot).createSync(recursive: true);
        final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();

        const String hash = '55109a4bed52acc780530f7a9aeff6c0';
        fakeSkiaClient.expectationForTestValues['flutter.golden_test.1'] = hash;
        fakeSkiaClient.imageBytesValues[hash] =_kTestPngBytes;
        fakeSkiaClient.cleanTestNameValues['library.flutter.golden_test.1.png'] = 'flutter.golden_test.1';
        final FakeDirectory fakeDirectory = FakeDirectory();
        fakeDirectory.existsSyncValue = true;
        fakeDirectory.uri = Uri.parse('/flutter');

        fakeSkiaClient.getExpectationForTestThrowable = const OSError("Can't reach Gold");
        final FlutterGoldenFileComparator comparator1 = await FlutterLocalFileComparator.fromDefaultComparator(
          platform,
          goldens: fakeSkiaClient,
          baseDirectory: fakeDirectory,
          log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
          fs: fs,
        );
        expect(comparator1.runtimeType, FlutterSkippingFileComparator);

        fakeSkiaClient.getExpectationForTestThrowable =  const SocketException("Can't reach Gold");
        final FlutterGoldenFileComparator comparator2 = await FlutterLocalFileComparator.fromDefaultComparator(
          platform,
          goldens: fakeSkiaClient,
          baseDirectory: fakeDirectory,
          log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
          fs: fs,
        );
        expect(comparator2.runtimeType, FlutterSkippingFileComparator);

        fakeSkiaClient.getExpectationForTestThrowable =  const FormatException("Can't reach Gold");
        final FlutterGoldenFileComparator comparator3 = await FlutterLocalFileComparator.fromDefaultComparator(
          platform,
          goldens: fakeSkiaClient,
          baseDirectory: fakeDirectory,
          log: (String message) => fail('skia gold client printed unexpected output: "$message"'),
          fs: fs,
        );
        expect(comparator3.runtimeType, FlutterSkippingFileComparator);

        // reset property or it will carry on to other tests
        fakeSkiaClient.getExpectationForTestThrowable = null;
      });
    });
  });
}

@immutable
class RunInvocation {
  const RunInvocation(this.command, this.workingDirectory);

  final List<String> command;
  final String? workingDirectory;

  @override
  int get hashCode => Object.hash(Object.hashAll(command), workingDirectory);

  bool _commandEquals(List<String> other) {
    if (other == command) {
      return true;
    }
    if (other.length != command.length) {
      return false;
    }
    for (int index = 0; index < other.length; index += 1) {
      if (other[index] != command[index]) {
        return false;
      }
    }
    return true;
  }

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is RunInvocation
        && _commandEquals(other.command)
        && other.workingDirectory == workingDirectory;
  }

  @override
  String toString() => '$command ($workingDirectory)';
}

class FakeProcessManager extends Fake implements ProcessManager {
  Map<RunInvocation, ProcessResult> processResults = <RunInvocation, ProcessResult>{};

  /// Used if [processResults] does not contain a matching invocation.
  ProcessResult? fallbackProcessResult;

  final List<String?> workingDirectories = <String?>[];

  @override
  Future<ProcessResult> run(
    List<Object> command, {
    String? workingDirectory,
    Map<String, String>? environment,
    bool includeParentEnvironment = true,
    bool runInShell = false,
    Encoding? stdoutEncoding = systemEncoding,
    Encoding? stderrEncoding = systemEncoding,
  }) async {
    workingDirectories.add(workingDirectory);
    final ProcessResult? result = processResults[RunInvocation(command.cast<String>(), workingDirectory)];
    if (result == null && fallbackProcessResult == null) {
      printOnFailure('ProcessManager.run was called with $command ($workingDirectory) unexpectedly - $processResults.');
      fail('See above.');
    }
    return result ?? fallbackProcessResult!;
  }
}

// See also dev/automated_tests/flutter_test/flutter_gold_test.dart
class FakeSkiaGoldClient extends Fake implements SkiaGoldClient {
  Map<String, String> expectationForTestValues = <String, String>{};
  Exception? getExpectationForTestThrowable;
  @override
  Future<String> getExpectationForTest(String testName) async {
    if (getExpectationForTestThrowable != null) {
      throw getExpectationForTestThrowable!;
    }
    return expectationForTestValues[testName] ?? '';
  }

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

  final List<String> testNames = <String>[];

  int initCalls = 0;
  @override
  Future<void> imgtestInit() async => initCalls += 1;
  @override
  Future<bool> imgtestAdd(String testName, File goldenFile) async {
    testNames.add(testName);
    return true;
  }

  int tryInitCalls = 0;
  @override
  Future<void> tryjobInit() async => tryInitCalls += 1;
  @override
  Future<bool> tryjobAdd(String testName, File goldenFile) async => true;

  Map<String, List<int>> imageBytesValues = <String, List<int>>{};
  @override
  Future<List<int>> getImageBytes(String imageHash) async => imageBytesValues[imageHash]!;

  Map<String, String> cleanTestNameValues = <String, String>{};
  @override
  String cleanTestName(String fileName) => cleanTestNameValues[fileName] ?? '';
}

class FakeLocalFileComparator extends Fake implements LocalFileComparator {
  @override
  late Uri basedir;
}

class FakeDirectory extends Fake implements Directory {
  late bool existsSyncValue;
  @override
  bool existsSync() => existsSyncValue;

  @override
  late Uri uri;
}

class FakeHttpClient extends Fake implements HttpClient {
  late Uri lastUri;
  late FakeHttpClientRequest request;

  @override
  Future<HttpClientRequest> getUrl(Uri url) async {
    lastUri = url;
    return request;
  }
}

class FakeHttpClientRequest extends Fake implements HttpClientRequest {
  late FakeHttpImageResponse response;

  @override
  Future<HttpClientResponse> close() async {
    return response;
  }
}

class FakeHttpImageResponse extends Fake implements HttpClientResponse {
  FakeHttpImageResponse(this.response);

  final List<List<int>> response;

  @override
  Future<void> forEach(void Function(List<int> element) action) async {
    response.forEach(action);
  }
}
