// 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: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';

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() {
  late MemoryFileSystem fs;
  late FakePlatform platform;
  late FakeProcessManager process;
  late FakeHttpClient fakeHttpClient;

  setUp(() {
    fs = MemoryFileSystem();
    platform = FakePlatform(
      environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
      operatingSystem: 'macos'
    );
    process = FakeProcessManager();
    fakeHttpClient = FakeHttpClient();
    fs.directory(_kFlutterRoot).createSync(recursive: true);
  });

  group('SkiaGoldClient', () {
    late SkiaGoldClient skiaClient;
    late Directory workDirectory;

    setUp(() {
      workDirectory = fs.directory('/workDirectory')
        ..createSync(recursive: true);
      skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
      );
    });

    test('web HTML test', () async {
      platform = FakePlatform(
        environment: <String, String>{
          'GOLDCTL': 'goldctl',
          'FLUTTER_ROOT': _kFlutterRoot,
          'FLUTTER_TEST_BROWSER': 'Chrome',
          'FLUTTER_WEB_RENDERER': 'html',
        },
        operatingSystem: 'macos'
      );
      skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
      );

      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 {
      platform = FakePlatform(
        environment: <String, String>{
          'GOLDCTL': 'goldctl',
          'FLUTTER_ROOT': _kFlutterRoot,
          'FLUTTER_TEST_BROWSER': 'Chrome',
          'FLUTTER_WEB_RENDERER': 'canvaskit',
        },
        operatingSystem: 'macos'
      );
      skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
      );

      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 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 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 {
      platform = FakePlatform(
        environment: <String, String>{
          'FLUTTER_ROOT': _kFlutterRoot,
          'GOLD_SERVICE_ACCOUNT' : 'Service Account',
          'GOLDCTL' : 'goldctl',
        },
        operatingSystem: 'macos'
      );

      skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
      );

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

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

    test('throws for error state from init', () {
      platform = FakePlatform(
        environment: <String, String>{
          'FLUTTER_ROOT': _kFlutterRoot,
          'GOLDCTL' : 'goldctl',
        },
        operatingSystem: 'macos'
      );

      skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
      );

      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 {
      platform = FakePlatform(
        environment: <String, String>{
          'FLUTTER_ROOT': _kFlutterRoot,
          'GOLDCTL' : 'goldctl',
        },
        operatingSystem: 'macos'
      );

      skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
      );

      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 {
      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'
      );

      skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
      );

      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 File goldenFile = fs.file('/workDirectory/temp/golden_file_test.png')
        ..createSync(recursive: true);
      platform = FakePlatform(
          environment: <String, String>{
            'FLUTTER_ROOT': _kFlutterRoot,
            'GOLDCTL' : 'goldctl',
          },
          operatingSystem: 'macos'
      );

      skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
      );

      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 {
      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'
      );

      skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
      );

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

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

    test('Creates traceID correctly', () async {
      String traceID;
      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'
      );

      skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
      );

      traceID = skiaClient.getTraceID('flutter.golden.1');
      expect(
        traceID,
        equals('ae18c7a6aa48e0685525dfe8fdf79003'),
      );

      // Browser
      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'
      );

      skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
      );

      traceID = skiaClient.getTraceID('flutter.golden.1');
      expect(
        traceID,
        equals('e9d5c296c48e7126808520e9cc191243'),
      );

      // Locally - should defer to luci traceID
      platform = FakePlatform(
        environment: <String, String>{
          'FLUTTER_ROOT': _kFlutterRoot,
        },
        operatingSystem: 'macos'
      );

      skiaClient = SkiaGoldClient(
        workDirectory,
        fs: fs,
        process: process,
        platform: platform,
        httpClient: fakeHttpClient,
      );

      traceID = skiaClient.getTraceID('flutter.golden.1');
      expect(
        traceID,
        equals('9968695b9ae78cdb77cbb2be621ca2d6'),
      );
    });

    group('Request Handling', () {
      const String expectation = '55109a4bed52acc780530f7a9aeff6c0';

      test('image bytes are processed properly', () async {
        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', () {
    late FlutterGoldenFileComparator comparator;

    setUp(() {
      final Directory basedir = fs.directory('flutter/test/library/')
        ..createSync(recursive: true);
      comparator = FlutterPostSubmitFileComparator(
        basedir.uri,
        FakeSkiaGoldClient(),
        fs: fs,
        platform: platform,
      );
    });

    test('calculates the basedir correctly from defaultComparator for local testing', () async {
      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,
      );
      expect(
        basedir.uri,
        fs.directory('/flutter/bin/cache/pkg/skia_goldens/baz').uri,
      );
    });

    test('ignores version number', () {
      final Uri key = comparator.getTestUri(Uri.parse('foo.png'), 1);
      expect(key, Uri.parse('foo.png'));
    });

    test('adds namePrefix', () async {
      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,
      );
      await comparator.compare(
        Uint8List.fromList(_kTestPngBytes),
        Uri.parse(fileName),
      );
      expect(fakeSkiaClient.testNames.single, '$namePrefix.$libraryName.$fileName');
    });

    group('Post-Submit', () {
      late FakeSkiaGoldClient fakeSkiaClient;

      setUp(() {
        fakeSkiaClient = FakeSkiaGoldClient();
        final Directory basedir = fs.directory('flutter/test/library/')
          ..createSync(recursive: true);
        comparator = FlutterPostSubmitFileComparator(
          basedir.uri,
          fakeSkiaClient,
          fs: fs,
          platform: platform,
        );
      });

      test('asserts .png format', () async {
        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.'
              ),
            ),
          ),
        );
      });

      test('calls init during compare', () {
        expect(fakeSkiaClient.initCalls, 0);
        comparator.compare(
          Uint8List.fromList(_kTestPngBytes),
          Uri.parse('flutter.golden_test.1.png'),
        );
        expect(fakeSkiaClient.initCalls, 1);
      });

      test('does not call init in during construction', () {
        expect(fakeSkiaClient.initCalls, 0);
        FlutterPostSubmitFileComparator.fromDefaultComparator(
          platform,
          goldens: fakeSkiaClient,
        );
        expect(fakeSkiaClient.initCalls, 0);
      });

      group('correctly determines testing environment', () {
        test('returns true for configured Luci', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'SWARMING_TASK_ID' : '12345678990',
              'GOLDCTL' : 'goldctl',
            },
            operatingSystem: 'macos',
          );
          expect(
            FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform),
            isTrue,
          );
        });

        test('returns false - GOLDCTL not present', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'SWARMING_TASK_ID' : '12345678990',
            },
            operatingSystem: 'macos',
          );
          expect(
            FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });

        test('returns false - GOLD_TRYJOB active', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'SWARMING_TASK_ID' : '12345678990',
              'GOLDCTL' : 'goldctl',
              'GOLD_TRYJOB' : 'git/ref/12345/head',
            },
            operatingSystem: 'macos',
          );
          expect(
            FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });

        test('returns false - on Cirrus', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'CIRRUS_CI': 'true',
              'CIRRUS_PR': '',
              'CIRRUS_BRANCH': 'master',
              'GOLD_SERVICE_ACCOUNT': 'service account...',
            },
            operatingSystem: 'macos',
          );
          expect(
            FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });
      });
    });

    group('Pre-Submit', () {
      late FakeSkiaGoldClient fakeSkiaClient;

      setUp(() {
        fakeSkiaClient = FakeSkiaGoldClient();
        final Directory basedir = fs.directory('flutter/test/library/')
          ..createSync(recursive: true);
        comparator = FlutterPreSubmitFileComparator(
          basedir.uri,
          fakeSkiaClient,
          fs: fs,
          platform: platform,
        );
      });

      test('asserts .png format', () async {
        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.'
              ),
            ),
          ),
        );
      });

      test('calls init during compare', () {
        expect(fakeSkiaClient.tryInitCalls, 0);
        comparator.compare(
          Uint8List.fromList(_kTestPngBytes),
          Uri.parse('flutter.golden_test.1.png'),
        );
        expect(fakeSkiaClient.tryInitCalls, 1);
      });

      test('does not call init in during construction', () {
        expect(fakeSkiaClient.tryInitCalls, 0);
        FlutterPostSubmitFileComparator.fromDefaultComparator(
          platform,
          goldens: fakeSkiaClient,
        );
        expect(fakeSkiaClient.tryInitCalls, 0);
      });

      group('correctly determines testing environment', () {
        test('returns true for Luci', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'SWARMING_TASK_ID' : '12345678990',
              'GOLDCTL' : 'goldctl',
              'GOLD_TRYJOB' : 'git/ref/12345/head',
            },
            operatingSystem: 'macos',
          );
          expect(
            FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
            isTrue,
          );
        });

        test('returns false - not on Luci', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
            },
            operatingSystem: 'macos',
          );
          expect(
            FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });

        test('returns false - GOLDCTL missing', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'SWARMING_TASK_ID' : '12345678990',
              'GOLD_TRYJOB' : 'git/ref/12345/head',
            },
            operatingSystem: 'macos',
          );
          expect(
            FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });

        test('returns false - GOLD_TRYJOB missing', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'SWARMING_TASK_ID' : '12345678990',
              'GOLDCTL' : 'goldctl',
            },
            operatingSystem: 'macos',
          );
          expect(
            FlutterPreSubmitFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });

        test('returns false - on Cirrus', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'CIRRUS_CI': 'true',
              'CIRRUS_PR': '',
              'CIRRUS_BRANCH': 'master',
              'GOLD_SERVICE_ACCOUNT': 'service account...',
            },
            operatingSystem: 'macos',
          );
          expect(
            FlutterPostSubmitFileComparator.isAvailableForEnvironment(platform),
            isFalse,
          );
        });
      });
    });

    group('Skipping', () {
      group('correctly determines testing environment', () {
        test('returns true on Cirrus builds', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'CIRRUS_CI' : 'yep',
            },
            operatingSystem: 'macos',
          );
          expect(
            FlutterSkippingFileComparator.isAvailableForEnvironment(platform),
            isTrue,
          );
        });

        test('returns true on irrelevant LUCI builds', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
              'SWARMING_TASK_ID' : '1234567890',
            },
            operatingSystem: 'macos'
          );
          expect(
            FlutterSkippingFileComparator.isAvailableForEnvironment(platform),
            isTrue,
          );
        });

        test('returns false - no CI', () {
          platform = FakePlatform(
            environment: <String, String>{
              'FLUTTER_ROOT': _kFlutterRoot,
            },
            operatingSystem: 'macos',
          );
          expect(
            FlutterSkippingFileComparator.isAvailableForEnvironment(
              platform),
            isFalse,
          );
        });
      });
    });

    group('Local', () {
      late FlutterLocalFileComparator comparator;
      final FakeSkiaGoldClient fakeSkiaClient = FakeSkiaGoldClient();

      setUp(() async {
        final Directory basedir = fs.directory('flutter/test/library/')
          ..createSync(recursive: true);
        comparator = FlutterLocalFileComparator(
          basedir.uri,
          fakeSkiaClient,
          fs: fs,
          platform: FakePlatform(
            environment: <String, String>{'FLUTTER_ROOT': _kFlutterRoot},
            operatingSystem: 'macos',
          ),
        );

        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';
      });

      test('asserts .png format', () async {
        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.'
              ),
            ),
          ),
        );
      });

      test('passes when bytes match', () async {
        expect(
          await comparator.compare(
            Uint8List.fromList(_kTestPngBytes),
            Uri.parse('flutter.golden_test.1.png'),
          ),
          isTrue,
        );
      });

      test('returns FlutterSkippingGoldenFileComparator when network connection is unavailable', () async {
        final FakeDirectory fakeDirectory = FakeDirectory();
        fakeDirectory.existsSyncValue = true;
        fakeDirectory.uri = Uri.parse('/flutter');

        fakeSkiaClient.getExpectationForTestThrowable = const OSError("Can't reach Gold");

        FlutterGoldenFileComparator comparator = await FlutterLocalFileComparator.fromDefaultComparator(
          platform,
          goldens: fakeSkiaClient,
          baseDirectory: fakeDirectory,
        );
        expect(comparator.runtimeType, FlutterSkippingFileComparator);

        fakeSkiaClient.getExpectationForTestThrowable =  const SocketException("Can't reach Gold");

        comparator = await FlutterLocalFileComparator.fromDefaultComparator(
          platform,
          goldens: fakeSkiaClient,
          baseDirectory: fakeDirectory,
        );
        expect(comparator.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);
  }
}
