// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import 'dart:convert';
import 'dart:io' show ProcessResult;
import 'dart:typed_data';

import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:path/path.dart' as path;
import 'package:platform/platform.dart' show FakePlatform, Platform;

import '../../../packages/flutter_tools/test/src/fake_process_manager.dart';
import '../prepare_package/archive_creator.dart';
import '../prepare_package/archive_publisher.dart';
import '../prepare_package/common.dart';
import '../prepare_package/process_runner.dart';
import '../prepare_package/transactional_update.dart';
import 'common.dart';

void main() {
  const testRef = 'deadbeefdeadbeefdeadbeefdeadbeefdeadbeef';

  test('PreparePackageException string includes class name and stderr', () {
    final exception = PreparePackageException(
      'failed to prepare package',
      ProcessResult(0, 1, '', 'stderr details'),
    );

    expect(
      exception.toString(),
      'PreparePackageException: failed to prepare package:\nstderr details',
    );
  });

  test('Throws on missing executable', () async {
    // Uses a *real* process manager, since we want to know what happens if
    // it can't find an executable.
    final processRunner = ProcessRunner(subprocessOutput: false);
    expect(
      expectAsync1((List<String> commandLine) async {
        return processRunner.runProcess(commandLine);
      })(<String>['this_executable_better_not_exist_2857632534321']),
      throwsA(isA<PreparePackageException>()),
    );

    await expectLater(
      () => processRunner.runProcess(<String>['this_executable_better_not_exist_2857632534321']),
      throwsA(
        isA<PreparePackageException>().having(
          (PreparePackageException error) => error.message,
          'message',
          contains(
            'ProcessException: Failed to find "this_executable_better_not_exist_2857632534321" in the search path',
          ),
        ),
      ),
    );
  });
  for (final platformName in <String>[Platform.macOS, Platform.linux, Platform.windows]) {
    final platform = FakePlatform(
      operatingSystem: platformName,
      environment: <String, String>{
        'DEPOT_TOOLS': platformName == Platform.windows
            ? path.join('D:', 'depot_tools')
            : '/depot_tools',
      },
    );
    group('ProcessRunner for $platform', () {
      test('Returns stdout', () async {
        final fakeProcessManager = FakeProcessManager.list(<FakeCommand>[
          const FakeCommand(command: <String>['echo', 'test'], stdout: 'output', stderr: 'error'),
        ]);
        final processRunner = ProcessRunner(
          subprocessOutput: false,
          platform: platform,
          processManager: fakeProcessManager,
        );
        final String output = await processRunner.runProcess(<String>['echo', 'test']);
        expect(output, equals('output'));
      });
      test('Throws on process failure', () async {
        final fakeProcessManager = FakeProcessManager.list(<FakeCommand>[
          const FakeCommand(
            command: <String>['echo', 'test'],
            stdout: 'output',
            stderr: 'error',
            exitCode: -1,
          ),
        ]);
        final processRunner = ProcessRunner(
          subprocessOutput: false,
          platform: platform,
          processManager: fakeProcessManager,
        );
        expect(
          expectAsync1((List<String> commandLine) async {
            return processRunner.runProcess(commandLine);
          })(<String>['echo', 'test']),
          throwsA(isA<PreparePackageException>()),
        );
      });
    });

    group('ArchiveCreator for $platformName', () {
      late ArchiveCreator creator;
      late Directory tempDir;
      Directory flutterDir;
      Directory cacheDir;
      late FakeProcessManager processManager;
      late FileSystem fs;
      final args = <List<String>>[];
      final namedArgs = <Map<Symbol, Object?>>[];
      late String flutter;
      late String dart;

      Future<Uint8List> fakeHttpReader(Uri url, {Map<String, String>? headers}) {
        return Future<Uint8List>.value(Uint8List(0));
      }

      setUp(() async {
        processManager = FakeProcessManager.list(<FakeCommand>[]);
        args.clear();
        namedArgs.clear();
        fs = MemoryFileSystem.test();
        tempDir = fs.systemTempDirectory;
        flutterDir = fs.directory(path.join(tempDir.path, 'flutter'));
        flutterDir.createSync(recursive: true);
        cacheDir = fs.directory(path.join(flutterDir.path, 'bin', 'cache'));
        cacheDir.createSync(recursive: true);
        creator = ArchiveCreator(
          tempDir,
          tempDir,
          testRef,
          Branch.beta,
          fs: fs,
          processManager: processManager,
          subprocessOutput: false,
          platform: platform,
          httpReader: fakeHttpReader,
        );
        flutter = path.join(creator.flutterRoot.absolute.path, 'bin', 'flutter');
        dart = path.join(
          creator.flutterRoot.absolute.path,
          'bin',
          'cache',
          'dart-sdk',
          'bin',
          'dart',
        );
      });

      tearDown(() async {
        tryToDelete(tempDir);
      });

      /// The subprocesses expected during archive creation, keyed by command-line.
      ///
      /// [dartArch] is the architecture `dart --version` reports for the Dart
      /// SDK downloaded into the archive. [archiveArch] is the architecture
      /// expected in the archive filename, or null for x64, which is unadorned.
      /// [precacheArgs] are appended to the `flutter precache` invocation.
      Map<String, List<ProcessResult>?> expectedCalls({
        required String dartArch,
        String? archiveArch,
        List<String> precacheArgs = const <String>[],
      }) {
        final String createBase = path.join(tempDir.absolute.path, 'create_');
        final archPrefix = archiveArch == null ? '' : '${archiveArch}_';
        final String archiveName = path.join(
          tempDir.absolute.path,
          'flutter_${platformName}_${archPrefix}v1.2.3-beta'
          '${platform.isLinux ? '.tar.xz' : '.zip'}',
        );
        return <String, List<ProcessResult>?>{
          'git clone -b beta https://flutter.googlesource.com/mirrors/flutter': null,
          'git reset --hard $testRef': null,
          'git remote set-url origin https://github.com/flutter/flutter.git': null,
          'git gc --prune=now --aggressive': null,
          'git describe --tags --exact-match $testRef': <ProcessResult>[
            ProcessResult(0, 0, 'v1.2.3', ''),
          ],
          '$flutter --version --machine': <ProcessResult>[
            ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''),
            ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''),
          ],
          '$dart --version': <ProcessResult>[
            ProcessResult(
              0,
              0,
              'Dart SDK version: 2.17.0-63.0.beta (beta) (Wed Jan 26 03:48:52 2022 -0800) on "${platformName}_$dartArch"',
              '',
            ),
          ],
          if (platform.isWindows) '7za x ${path.join(tempDir.path, 'mingit.zip')}': null,
          '$flutter doctor': null,
          '$flutter update-packages': null,
          <String>['$flutter precache', ...precacheArgs].join(' '): null,
          '$flutter ide-config': null,
          '$flutter create --template=app ${createBase}app': null,
          '$flutter create --template=package ${createBase}package': null,
          '$flutter create --template=plugin ${createBase}plugin': null,
          '$flutter pub cache list': <ProcessResult>[ProcessResult(0, 0, '{"packages":{}}', '')],
          'git clean -f -x -- **/.packages': null,
          'git clean -f -x -- **/.dart_tool/': null,
          if (platform.isMacOS)
            'codesign -vvvv --check-notarization ${path.join(tempDir.path, 'flutter', 'bin', 'cache', 'dart-sdk', 'bin', 'dart')}':
                null,
          if (platform.isWindows) 'attrib -h .git': null,
          if (platform.isWindows)
            '7za a -tzip -mx=9 $archiveName flutter': null
          else if (platform.isMacOS)
            'zip -r -9 --symlinks $archiveName flutter': null
          else if (platform.isLinux)
            'tar cJf $archiveName --verbose flutter': null,
        };
      }

      /// The environment expected on every [ArchiveCreator] subprocess.
      ///
      /// This is the ambient environment, plus the archive's own pub cache,
      /// plus the host architecture override when one was requested.
      Map<String, String> expectedEnvironment({TargetArch? targetArch}) {
        return <String, String>{
          ...platform.environment,
          'PUB_CACHE': path.join(tempDir.path, '.pub-cache'),
          if (targetArch != null) 'FLUTTER_HOST_ARCH': targetArch.name,
        };
      }

      test('sets PUB_CACHE properly', () async {
        processManager.addCommands(
          convertResults(expectedCalls(dartArch: 'x64'), environment: expectedEnvironment()),
        );
        await creator.initializeRepo();
        await creator.createArchive();
      });

      test('calls the right commands for archive output', () async {
        processManager.addCommands(convertResults(expectedCalls(dartArch: 'x64')));
        await creator.initializeRepo();
        await creator.createArchive();
      });

      test('adds the arch name to the archive for non-x64', () async {
        processManager.addCommands(
          convertResults(expectedCalls(dartArch: 'arm64', archiveArch: 'arm64')),
        );
        await creator.initializeRepo();
        await creator.createArchive();
      });

      test('targetArch drives the precache arch and the tool environment', () async {
        processManager.addCommands(
          convertResults(
            expectedCalls(dartArch: 'x64', precacheArgs: <String>['--host-arch=x64']),
            environment: expectedEnvironment(targetArch: TargetArch.x64),
          ),
        );
        creator = ArchiveCreator(
          tempDir,
          tempDir,
          testRef,
          Branch.beta,
          fs: fs,
          processManager: processManager,
          subprocessOutput: false,
          platform: platform,
          httpReader: fakeHttpReader,
          targetArch: TargetArch.x64,
        );
        await creator.initializeRepo();
        await creator.createArchive();
      });

      test('targetArch names a non-x64 archive after the requested arch', () async {
        processManager.addCommands(
          convertResults(
            expectedCalls(
              dartArch: 'arm64',
              archiveArch: 'arm64',
              precacheArgs: <String>['--host-arch=arm64'],
            ),
            environment: expectedEnvironment(targetArch: TargetArch.arm64),
          ),
        );
        creator = ArchiveCreator(
          tempDir,
          tempDir,
          testRef,
          Branch.beta,
          fs: fs,
          processManager: processManager,
          subprocessOutput: false,
          platform: platform,
          httpReader: fakeHttpReader,
          targetArch: TargetArch.arm64,
        );
        await creator.initializeRepo();
        await creator.createArchive();
      });

      test('throws if the archived Dart SDK does not match targetArch', () async {
        // The requested arch names the archive, but the arch published in the
        // release metadata comes from the Dart SDK that was downloaded, so a
        // disagreement has to fail the build rather than ship a mislabelled
        // archive.
        //
        // The mismatch is caught in initializeRepo, so only the commands up to
        // and including `dart --version` are ever run.
        final Map<String, List<ProcessResult>?> calls = expectedCalls(dartArch: 'arm64');
        final int callsBeforeThrow = calls.keys.toList().indexOf('$dart --version') + 1;
        processManager.addCommands(
          convertResults(
            Map<String, List<ProcessResult>?>.fromEntries(calls.entries.take(callsBeforeThrow)),
          ),
        );
        creator = ArchiveCreator(
          tempDir,
          tempDir,
          testRef,
          Branch.beta,
          fs: fs,
          processManager: processManager,
          subprocessOutput: false,
          platform: platform,
          httpReader: fakeHttpReader,
          targetArch: TargetArch.x64,
        );
        await expectLater(
          creator.initializeRepo,
          throwsA(
            isA<PreparePackageException>().having(
              (PreparePackageException error) => error.message,
              'message',
              contains('Requested an archive for x64, but the Dart SDK in the archive is arm64'),
            ),
          ),
        );
      });

      test('throws when a command errors out', () async {
        final calls = <String, List<ProcessResult>>{
          'git clone -b beta https://flutter.googlesource.com/mirrors/flutter': <ProcessResult>[
            ProcessResult(0, 0, 'output1', ''),
          ],
          'git reset --hard $testRef': <ProcessResult>[ProcessResult(0, -1, 'output2', '')],
        };
        processManager.addCommands(convertResults(calls));
        expect(expectAsync0(creator.initializeRepo), throwsA(isA<PreparePackageException>()));
      });

      test('non-strict mode calls the right commands', () async {
        final String createBase = path.join(tempDir.absolute.path, 'create_');
        final String archiveName = path.join(
          tempDir.absolute.path,
          'flutter_${platformName}_v1.2.3-beta${platform.isLinux ? '.tar.xz' : '.zip'}',
        );
        final calls = <String, List<ProcessResult>?>{
          'git clone -b beta https://flutter.googlesource.com/mirrors/flutter': null,
          'git reset --hard $testRef': null,
          'git remote set-url origin https://github.com/flutter/flutter.git': null,
          'git gc --prune=now --aggressive': null,
          'git describe --tags --abbrev=0 $testRef': <ProcessResult>[
            ProcessResult(0, 0, 'v1.2.3', ''),
          ],
          '$flutter --version --machine': <ProcessResult>[
            ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''),
            ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''),
          ],
          '$dart --version': <ProcessResult>[
            ProcessResult(
              0,
              0,
              'Dart SDK version: 2.17.0-63.0.beta (beta) (Wed Jan 26 03:48:52 2022 -0800) on "${platformName}_x64"',
              '',
            ),
          ],
          if (platform.isWindows) '7za x ${path.join(tempDir.path, 'mingit.zip')}': null,
          '$flutter doctor': null,
          '$flutter update-packages': null,
          '$flutter precache': null,
          '$flutter ide-config': null,
          '$flutter create --template=app ${createBase}app': null,
          '$flutter create --template=package ${createBase}package': null,
          '$flutter create --template=plugin ${createBase}plugin': null,
          '$flutter pub cache list': <ProcessResult>[ProcessResult(0, 0, '{"packages":{}}', '')],
          'git clean -f -x -- **/.packages': null,
          'git clean -f -x -- **/.dart_tool/': null,
          if (platform.isWindows) 'attrib -h .git': null,
          if (platform.isWindows)
            '7za a -tzip -mx=9 $archiveName flutter': null
          else if (platform.isMacOS)
            'zip -r -9 --symlinks $archiveName flutter': null
          else if (platform.isLinux)
            'tar cJf $archiveName --verbose flutter': null,
        };
        processManager.addCommands(convertResults(calls));
        creator = ArchiveCreator(
          tempDir,
          tempDir,
          testRef,
          Branch.beta,
          fs: fs,
          strict: false,
          processManager: processManager,
          subprocessOutput: false,
          platform: platform,
          httpReader: fakeHttpReader,
        );
        await creator.initializeRepo();
        await creator.createArchive();
      });

      test('fails if binary is not codesigned', () async {
        final String createBase = path.join(tempDir.absolute.path, 'create_');
        final String archiveName = path.join(
          tempDir.absolute.path,
          'flutter_${platformName}_v1.2.3-beta${platform.isLinux ? '.tar.xz' : '.zip'}',
        );
        final codesignFailure = ProcessResult(1, 1, '', 'code object is not signed at all');
        final String binPath = path.join(
          tempDir.path,
          'flutter',
          'bin',
          'cache',
          'dart-sdk',
          'bin',
          'dart',
        );
        final calls = <String, List<ProcessResult>?>{
          'git clone -b beta https://flutter.googlesource.com/mirrors/flutter': null,
          'git reset --hard $testRef': null,
          'git remote set-url origin https://github.com/flutter/flutter.git': null,
          'git gc --prune=now --aggressive': null,
          'git describe --tags --exact-match $testRef': <ProcessResult>[
            ProcessResult(0, 0, 'v1.2.3', ''),
          ],
          '$flutter --version --machine': <ProcessResult>[
            ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''),
            ProcessResult(0, 0, '{"dartSdkVersion": "3.2.1"}', ''),
          ],
          '$dart --version': <ProcessResult>[
            ProcessResult(
              0,
              0,
              'Dart SDK version: 2.17.0-63.0.beta (beta) (Wed Jan 26 03:48:52 2022 -0800) on "${platformName}_x64"',
              '',
            ),
          ],
          if (platform.isWindows) '7za x ${path.join(tempDir.path, 'mingit.zip')}': null,
          '$flutter doctor': null,
          '$flutter update-packages': null,
          '$flutter precache': null,
          '$flutter ide-config': null,
          '$flutter create --template=app ${createBase}app': null,
          '$flutter create --template=package ${createBase}package': null,
          '$flutter create --template=plugin ${createBase}plugin': null,
          '$flutter pub cache list': <ProcessResult>[ProcessResult(0, 0, '{"packages":{}}', '')],
          'git clean -f -x -- **/.packages': null,
          'git clean -f -x -- **/.dart_tool/': null,
          if (platform.isMacOS)
            'codesign -vvvv --check-notarization $binPath': <ProcessResult>[codesignFailure],
          if (platform.isWindows) 'attrib -h .git': null,
          if (platform.isWindows)
            '7za a -tzip -mx=9 $archiveName flutter': null
          else if (platform.isMacOS)
            'zip -r -9 --symlinks $archiveName flutter': null
          else if (platform.isLinux)
            'tar cJf $archiveName flutter': null,
        };
        processManager.addCommands(convertResults(calls));
        creator = ArchiveCreator(
          tempDir,
          tempDir,
          testRef,
          Branch.beta,
          fs: fs,
          processManager: processManager,
          subprocessOutput: false,
          platform: platform,
          httpReader: fakeHttpReader,
        );
        await creator.initializeRepo();

        await expectLater(
          () => creator.createArchive(),
          throwsA(
            isA<PreparePackageException>().having(
              (PreparePackageException exception) => exception.message,
              'message',
              contains('The binary $binPath was not codesigned!'),
            ),
          ),
        );
      }, skip: !platform.isMacOS); // [intended] codesign is only available on macOS
    });

    group('ArchivePublisher for $platformName', () {
      late FakeProcessManager processManager;
      late Directory tempDir;
      late FileSystem fs;
      final gsutilCall = platform.isWindows
          ? 'python3 ${path.join("D:", "depot_tools", "gsutil.py")}'
          : 'python3 ${path.join("/", "depot_tools", "gsutil.py")}';
      final releasesName = 'releases_$platformName.json';
      final archiveName = platform.isLinux ? 'archive.tar.xz' : 'archive.zip';
      final archiveMime = platform.isLinux ? 'application/x-gtar' : 'application/zip';
      final gsArchivePath = 'gs://flutter_infra_release/releases/stable/$platformName/$archiveName';

      setUp(() async {
        fs = MemoryFileSystem.test(
          style: platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix,
        );
        processManager = FakeProcessManager.list(<FakeCommand>[]);
        tempDir = fs.systemTempDirectory.createTempSync('flutter_prepage_package_test.');
      });

      tearDown(() async {
        tryToDelete(tempDir);
      });

      test('calls the right processes', () async {
        final String archivePath = path.join(tempDir.absolute.path, archiveName);
        final String jsonPath = path.join(tempDir.absolute.path, releasesName);
        final gsJsonPath = 'gs://flutter_infra_release/releases/$releasesName';
        final releasesJson =
            '''
{
  "base_url": "https://storage.googleapis.com/flutter_infra_release/releases",
  "current_release": {
    "beta": "3ea4d06340a97a1e9d7cae97567c64e0569dcaa2",
    "beta": "5a58b36e36b8d7aace89d3950e6deb307956a6a0"
  },
  "releases": [
    {
      "hash": "5a58b36e36b8d7aace89d3950e6deb307956a6a0",
      "channel": "beta",
      "version": "v0.2.3",
      "release_date": "2018-03-20T01:47:02.851729Z",
      "archive": "beta/$platformName/flutter_${platformName}_v0.2.3-beta.zip",
      "sha256": "4fe85a822093e81cb5a66c7fc263f68de39b5797b294191b6d75e7afcc86aff8",
      "dart_sdk_arch": "x64"
    },
    {
      "hash": "b9bd51cc36b706215915711e580851901faebb40",
      "channel": "beta",
      "version": "v0.2.2",
      "release_date": "2018-03-16T18:48:13.375013Z",
      "archive": "beta/$platformName/flutter_${platformName}_v0.2.2-beta.zip",
      "sha256": "6073331168cdb37a4637a5dc073d6a7ef4e466321effa2c529fa27d2253a4d4b",
      "dart_sdk_arch": "x64"
    },
    {
      "hash": "$testRef",
      "channel": "stable",
      "version": "v0.0.0",
      "release_date": "2018-03-20T01:47:02.851729Z",
      "archive": "stable/$platformName/flutter_${platformName}_v0.0.0-beta.zip",
      "sha256": "5dd34873b3a3e214a32fd30c2c319a0f46e608afb72f0d450b2d621a6d02aebd",
      "dart_sdk_arch": "x64"
    }
  ]
}
''';
        fs.file(jsonPath).writeAsStringSync(releasesJson);
        fs.file(fs.path.join(tempDir.path, 'downloaded.json')).createSync(recursive: true);
        fs.file(fs.path.join(tempDir.path, 'downloaded.json')).writeAsStringSync(releasesJson);
        fs.file(archivePath).writeAsStringSync('archive contents');
        final calls = <String, List<ProcessResult>?>{
          '$gsutilCall -- stat $gsArchivePath': <ProcessResult>[ProcessResult(0, 1, '', '')],
          '$gsutilCall -- rm $gsArchivePath': null,
          '$gsutilCall -- -h Content-Type:$archiveMime cp $archivePath $gsArchivePath': null,
          '$gsutilCall -- stat $gsJsonPath': <ProcessResult>[
            ProcessResult(0, 0, 'Generation: 12345', ''),
          ],
          '$gsutilCall -- cp $gsJsonPath#12345 ${fs.path.join(tempDir.path, "downloaded.json")}':
              null,
          '$gsutilCall -- -h x-goog-if-generation-match:12345 cp ${fs.path.join(tempDir.path, "upload.json")} $gsJsonPath':
              null,
        };
        processManager.addCommands(convertResults(calls));
        final File outputFile = fs.file(path.join(tempDir.absolute.path, archiveName));
        outputFile.createSync();
        assert(tempDir.existsSync());
        final publisher = ArchivePublisher(
          tempDir,
          testRef,
          Branch.stable,
          <String, String>{
            'frameworkVersionFromGit': 'v1.2.3',
            'dartSdkVersion': '3.2.1',
            'dartTargetArch': 'x64',
          },
          outputFile,
          false,
          fs: fs,
          processManager: processManager,
          subprocessOutput: false,
          platform: platform,
        );
        assert(tempDir.existsSync());
        await publisher.publishArchive();

        final File releaseFile = fs.file(fs.path.join(tempDir.path, 'upload.json'));
        expect(releaseFile.existsSync(), isTrue);
        final String contents = releaseFile.readAsStringSync();
        // Make sure new data is added.
        expect(contents, contains('"hash": "$testRef"'));
        expect(contents, contains('"channel": "stable"'));
        expect(contents, contains('"archive": "stable/$platformName/$archiveName"'));
        expect(
          contents,
          contains('"sha256": "f69f4865f861193a91d1c5544a894167a7137b788d10bac8edbf5d095f45cb4d"'),
        );
        // Make sure existing entries are preserved.
        expect(contents, contains('"hash": "5a58b36e36b8d7aace89d3950e6deb307956a6a0"'));
        expect(contents, contains('"hash": "b9bd51cc36b706215915711e580851901faebb40"'));
        expect(contents, contains('"channel": "beta"'));
        expect(contents, contains('"channel": "beta"'));
        // Make sure old matching entries are removed.
        expect(contents, isNot(contains('v0.0.0')));
        final jsonData = json.decode(contents) as Map<String, Object?>;
        final releases = jsonData['releases']! as List<Object?>;
        expect(releases.length, equals(3));
        // Make sure the new entry is first (and hopefully it takes less than a
        // minute to go from publishArchive above to this line!).
        expect(
          DateTime.now().difference(
            DateTime.parse((releases[0]! as Map<String, Object?>)['release_date']! as String),
          ),
          lessThan(const Duration(minutes: 1)),
        );
        const encoder = JsonEncoder.withIndent('  ');
        expect(contents, equals(encoder.convert(jsonData)));
      });

      test('contains Dart SDK version info', () async {
        final String archivePath = path.join(tempDir.absolute.path, archiveName);
        final String jsonPath = path.join(tempDir.absolute.path, releasesName);
        final gsJsonPath = 'gs://flutter_infra_release/releases/$releasesName';
        final releasesJson =
            '''
{
  "base_url": "https://storage.googleapis.com/flutter_infra_release/releases",
  "current_release": {
    "beta": "3ea4d06340a97a1e9d7cae97567c64e0569dcaa2",
    "beta": "5a58b36e36b8d7aace89d3950e6deb307956a6a0"
  },
  "releases": [
    {
      "hash": "5a58b36e36b8d7aace89d3950e6deb307956a6a0",
      "channel": "beta",
      "version": "v0.2.3",
      "release_date": "2018-03-20T01:47:02.851729Z",
      "archive": "beta/$platformName/flutter_${platformName}_v0.2.3-beta.zip",
      "sha256": "4fe85a822093e81cb5a66c7fc263f68de39b5797b294191b6d75e7afcc86aff8"
    },
    {
      "hash": "b9bd51cc36b706215915711e580851901faebb40",
      "channel": "beta",
      "version": "v0.2.2",
      "release_date": "2018-03-16T18:48:13.375013Z",
      "archive": "beta/$platformName/flutter_${platformName}_v0.2.2-beta.zip",
      "sha256": "6073331168cdb37a4637a5dc073d6a7ef4e466321effa2c529fa27d2253a4d4b"
    },
    {
      "hash": "$testRef",
      "channel": "stable",
      "version": "v0.0.0",
      "release_date": "2018-03-20T01:47:02.851729Z",
      "archive": "stable/$platformName/flutter_${platformName}_v0.0.0-beta.zip",
      "sha256": "5dd34873b3a3e214a32fd30c2c319a0f46e608afb72f0d450b2d621a6d02aebd"
    }
  ]
}
''';
        fs.file(jsonPath).writeAsStringSync(releasesJson);
        fs.file(fs.path.join(tempDir.path, 'downloaded.json')).createSync(recursive: true);
        fs.file(fs.path.join(tempDir.path, 'downloaded.json')).writeAsStringSync(releasesJson);
        fs.file(archivePath).writeAsStringSync('archive contents');
        final calls = <String, List<ProcessResult>?>{
          '$gsutilCall -- stat $gsArchivePath': <ProcessResult>[ProcessResult(0, 1, '', '')],
          '$gsutilCall -- rm $gsArchivePath': null,
          '$gsutilCall -- -h Content-Type:$archiveMime cp $archivePath $gsArchivePath': null,
          '$gsutilCall -- stat $gsJsonPath': <ProcessResult>[
            ProcessResult(0, 0, 'Generation: 12345', ''),
          ],
          '$gsutilCall -- cp $gsJsonPath#12345 ${fs.path.join(tempDir.path, "downloaded.json")}':
              null,
          '$gsutilCall -- -h x-goog-if-generation-match:12345 cp ${fs.path.join(tempDir.path, "upload.json")} $gsJsonPath':
              null,
        };
        processManager.addCommands(convertResults(calls));
        final File outputFile = fs.file(path.join(tempDir.absolute.path, archiveName));
        outputFile.createSync();
        assert(tempDir.existsSync());
        final publisher = ArchivePublisher(
          tempDir,
          testRef,
          Branch.stable,
          <String, String>{
            'frameworkVersionFromGit': 'v1.2.3',
            'dartSdkVersion': '3.2.1',
            'dartTargetArch': 'x64',
          },
          outputFile,
          false,
          fs: fs,
          processManager: processManager,
          subprocessOutput: false,
          platform: platform,
        );
        assert(tempDir.existsSync());
        await publisher.publishArchive();

        final File releaseFile = fs.file(fs.path.join(tempDir.path, 'upload.json'));
        expect(releaseFile.existsSync(), isTrue);
        final String contents = releaseFile.readAsStringSync();
        expect(contents, contains('"dart_sdk_version": "3.2.1"'));
        expect(contents, contains('"dart_sdk_arch": "x64"'));
      });

      test('Supports multiple architectures', () async {
        final String archivePath = path.join(tempDir.absolute.path, archiveName);
        final String jsonPath = path.join(tempDir.absolute.path, releasesName);
        final gsJsonPath = 'gs://flutter_infra_release/releases/$releasesName';
        final releasesJson =
            '''
{
  "base_url": "https://storage.googleapis.com/flutter_infra_release/releases",
  "current_release": {
    "beta": "3ea4d06340a97a1e9d7cae97567c64e0569dcaa2",
    "beta": "5a58b36e36b8d7aace89d3950e6deb307956a6a0"
  },
  "releases": [
    {
      "hash": "deadbeefdeadbeefdeadbeefdeadbeefdeadbeef",
      "channel": "stable",
      "version": "v1.2.3",
      "release_date": "2018-03-20T01:47:02.851729Z",
      "archive": "beta/$platformName/flutter_${platformName}_v0.2.3-beta.zip",
      "sha256": "4fe85a822093e81cb5a66c7fc263f68de39b5797b294191b6d75e7afcc86aff8",
      "dart_sdk_arch": "x64"
    }
  ]
}
''';
        fs.file(jsonPath).writeAsStringSync(releasesJson);
        fs.file(fs.path.join(tempDir.path, 'downloaded.json')).createSync(recursive: true);
        fs.file(fs.path.join(tempDir.path, 'downloaded.json')).writeAsStringSync(releasesJson);
        fs.file(archivePath).writeAsStringSync('archive contents');
        final calls = <String, List<ProcessResult>?>{
          '$gsutilCall -- stat $gsArchivePath': <ProcessResult>[ProcessResult(0, 1, '', '')],
          '$gsutilCall -- rm $gsArchivePath': null,
          '$gsutilCall -- -h Content-Type:$archiveMime cp $archivePath $gsArchivePath': null,
          '$gsutilCall -- stat $gsJsonPath': <ProcessResult>[
            ProcessResult(0, 0, 'Generation: 12345', ''),
          ],
          '$gsutilCall -- cp $gsJsonPath#12345 ${fs.path.join(tempDir.path, "downloaded.json")}':
              null,
          '$gsutilCall -- -h x-goog-if-generation-match:12345 cp ${fs.path.join(tempDir.path, "upload.json")} $gsJsonPath':
              null,
        };
        processManager.addCommands(convertResults(calls));
        final File outputFile = fs.file(path.join(tempDir.absolute.path, archiveName));
        outputFile.createSync();
        assert(tempDir.existsSync());
        final publisher = ArchivePublisher(
          tempDir,
          testRef,
          Branch.stable,
          <String, String>{
            'frameworkVersionFromGit': 'v1.2.3',
            'dartSdkVersion': '3.2.1',
            'dartTargetArch': 'arm64',
          },
          outputFile,
          false,
          fs: fs,
          processManager: processManager,
          subprocessOutput: false,
          platform: platform,
        );
        assert(tempDir.existsSync());

        await publisher.publishArchive();

        final File releaseFile = fs.file(fs.path.join(tempDir.path, 'upload.json'));
        expect(releaseFile.existsSync(), isTrue);
        final String contents = releaseFile.readAsStringSync();
        final releases = jsonDecode(contents) as Map<String, Object?>;
        expect((releases['releases']! as List<Object?>).length, equals(2));
      });

      test('updates base_url from old bucket to new bucket', () async {
        final String archivePath = path.join(tempDir.absolute.path, archiveName);
        final String jsonPath = path.join(tempDir.absolute.path, releasesName);
        final gsJsonPath = 'gs://flutter_infra_release/releases/$releasesName';
        final releasesJson =
            '''
{
  "base_url": "https://storage.googleapis.com/flutter_infra_release/releases",
  "current_release": {
    "beta": "3ea4d06340a97a1e9d7cae97567c64e0569dcaa2",
    "beta": "5a58b36e36b8d7aace89d3950e6deb307956a6a0"
  },
  "releases": [
    {
      "hash": "5a58b36e36b8d7aace89d3950e6deb307956a6a0",
      "channel": "beta",
      "version": "v0.2.3",
      "release_date": "2018-03-20T01:47:02.851729Z",
      "archive": "beta/$platformName/flutter_${platformName}_v0.2.3-beta.zip",
      "sha256": "4fe85a822093e81cb5a66c7fc263f68de39b5797b294191b6d75e7afcc86aff8"
    },
    {
      "hash": "b9bd51cc36b706215915711e580851901faebb40",
      "channel": "beta",
      "version": "v0.2.2",
      "release_date": "2018-03-16T18:48:13.375013Z",
      "archive": "beta/$platformName/flutter_${platformName}_v0.2.2-beta.zip",
      "sha256": "6073331168cdb37a4637a5dc073d6a7ef4e466321effa2c529fa27d2253a4d4b"
    },
    {
      "hash": "$testRef",
      "channel": "stable",
      "version": "v0.0.0",
      "release_date": "2018-03-20T01:47:02.851729Z",
      "archive": "stable/$platformName/flutter_${platformName}_v0.0.0-beta.zip",
      "sha256": "5dd34873b3a3e214a32fd30c2c319a0f46e608afb72f0d450b2d621a6d02aebd"
    }
  ]
}
''';
        fs.file(jsonPath).writeAsStringSync(releasesJson);
        fs.file(fs.path.join(tempDir.path, 'downloaded.json')).createSync(recursive: true);
        fs.file(fs.path.join(tempDir.path, 'downloaded.json')).writeAsStringSync(releasesJson);
        fs.file(archivePath).writeAsStringSync('archive contents');
        final calls = <String, List<ProcessResult>?>{
          '$gsutilCall -- stat $gsArchivePath': <ProcessResult>[ProcessResult(0, 1, '', '')],
          '$gsutilCall -- rm $gsArchivePath': null,
          '$gsutilCall -- -h Content-Type:$archiveMime cp $archivePath $gsArchivePath': null,
          '$gsutilCall -- stat $gsJsonPath': <ProcessResult>[
            ProcessResult(0, 0, 'Generation: 12345', ''),
          ],
          '$gsutilCall -- cp $gsJsonPath#12345 ${fs.path.join(tempDir.path, "downloaded.json")}':
              null,
          '$gsutilCall -- -h x-goog-if-generation-match:12345 cp ${fs.path.join(tempDir.path, "upload.json")} $gsJsonPath':
              null,
        };
        processManager.addCommands(convertResults(calls));
        final File outputFile = fs.file(path.join(tempDir.absolute.path, archiveName));
        outputFile.createSync();
        assert(tempDir.existsSync());
        final publisher = ArchivePublisher(
          tempDir,
          testRef,
          Branch.stable,
          <String, String>{
            'frameworkVersionFromGit': 'v1.2.3',
            'dartSdkVersion': '3.2.1',
            'dartTargetArch': 'x64',
          },
          outputFile,
          false,
          fs: fs,
          processManager: processManager,
          subprocessOutput: false,
          platform: platform,
        );
        assert(tempDir.existsSync());
        await publisher.publishArchive();

        final File releaseFile = fs.file(fs.path.join(tempDir.path, 'upload.json'));
        expect(releaseFile.existsSync(), isTrue);
        final String contents = releaseFile.readAsStringSync();
        final jsonData = json.decode(contents) as Map<String, Object?>;
        expect(
          jsonData['base_url'],
          'https://storage.googleapis.com/flutter_infra_release/releases',
        );
      });

      test('publishArchive throws if forceUpload is false and artifact already exists on cloud storage', () async {
        final archiveName = platform.isLinux ? 'archive.tar.xz' : 'archive.zip';
        final File outputFile = fs.file(path.join(tempDir.absolute.path, archiveName));
        final publisher = ArchivePublisher(
          tempDir,
          testRef,
          Branch.stable,
          <String, String>{
            'frameworkVersionFromGit': 'v1.2.3',
            'dartSdkVersion': '3.2.1',
            'dartTargetArch': 'x64',
          },
          outputFile,
          false,
          fs: fs,
          processManager: processManager,
          subprocessOutput: false,
          platform: platform,
        );
        final calls = <String, List<ProcessResult>>{
          // This process returns 0 because file already exists
          '$gsutilCall -- stat $gsArchivePath': <ProcessResult>[ProcessResult(0, 0, '', '')],
        };
        processManager.addCommands(convertResults(calls));
        expect(() async => publisher.publishArchive(), throwsException);
      });

      test('publishArchive does not throw if forceUpload is true and artifact already exists on cloud storage', () async {
        final archiveName = platform.isLinux ? 'archive.tar.xz' : 'archive.zip';
        final File outputFile = fs.file(path.join(tempDir.absolute.path, archiveName));
        final publisher = ArchivePublisher(
          tempDir,
          testRef,
          Branch.stable,
          <String, String>{
            'frameworkVersionFromGit': 'v1.2.3',
            'dartSdkVersion': '3.2.1',
            'dartTargetArch': 'x64',
          },
          outputFile,
          false,
          fs: fs,
          processManager: processManager,
          subprocessOutput: false,
          platform: platform,
        );
        final String archivePath = path.join(tempDir.absolute.path, archiveName);
        final String jsonPath = path.join(tempDir.absolute.path, releasesName);
        final gsJsonPath = 'gs://flutter_infra_release/releases/$releasesName';
        final releasesJson =
            '''
{
  "base_url": "https://storage.googleapis.com/flutter_infra_release/releases",
  "current_release": {
    "beta": "3ea4d06340a97a1e9d7cae97567c64e0569dcaa2",
    "beta": "5a58b36e36b8d7aace89d3950e6deb307956a6a0"
  },
  "releases": [
    {
      "hash": "5a58b36e36b8d7aace89d3950e6deb307956a6a0",
      "channel": "beta",
      "version": "v0.2.3",
      "release_date": "2018-03-20T01:47:02.851729Z",
      "archive": "beta/$platformName/flutter_${platformName}_v0.2.3-beta.zip",
      "sha256": "4fe85a822093e81cb5a66c7fc263f68de39b5797b294191b6d75e7afcc86aff8"
    },
    {
      "hash": "b9bd51cc36b706215915711e580851901faebb40",
      "channel": "beta",
      "version": "v0.2.2",
      "release_date": "2018-03-16T18:48:13.375013Z",
      "archive": "beta/$platformName/flutter_${platformName}_v0.2.2-beta.zip",
      "sha256": "6073331168cdb37a4637a5dc073d6a7ef4e466321effa2c529fa27d2253a4d4b"
    },
    {
      "hash": "$testRef",
      "channel": "stable",
      "version": "v0.0.0",
      "release_date": "2018-03-20T01:47:02.851729Z",
      "archive": "stable/$platformName/flutter_${platformName}_v0.0.0-beta.zip",
      "sha256": "5dd34873b3a3e214a32fd30c2c319a0f46e608afb72f0d450b2d621a6d02aebd"
    }
  ]
}
''';
        fs.file(jsonPath).writeAsStringSync(releasesJson);
        fs.file(fs.path.join(tempDir.path, 'downloaded.json')).createSync(recursive: true);
        fs.file(fs.path.join(tempDir.path, 'downloaded.json')).writeAsStringSync(releasesJson);
        fs.file(archivePath).writeAsStringSync('archive contents');
        final calls = <String, List<ProcessResult>?>{
          '$gsutilCall -- rm $gsArchivePath': null,
          '$gsutilCall -- -h Content-Type:$archiveMime cp $archivePath $gsArchivePath': null,
          '$gsutilCall -- stat $gsJsonPath': <ProcessResult>[
            ProcessResult(0, 0, 'Generation: 12345', ''),
          ],
          '$gsutilCall -- cp $gsJsonPath#12345 ${fs.path.join(tempDir.path, "downloaded.json")}':
              null,
          '$gsutilCall -- -h x-goog-if-generation-match:12345 cp ${fs.path.join(tempDir.path, "upload.json")} $gsJsonPath':
              null,
        };
        processManager.addCommands(convertResults(calls));
        assert(tempDir.existsSync());
        await publisher.publishArchive(true);
      });
    });

    group('transactionalUpdate', () {
      late FakeProcessManager processManager;
      late FileSystem fs;
      final gsutilCall = platform.isWindows
          ? 'python3 ${path.join("D:", "depot_tools", "gsutil.py")}'
          : 'python3 ${path.join("/", "depot_tools", "gsutil.py")}';
      const gsPath = 'gs://flutter_infra_release/releases/manifest.json';
      late Directory tempDirectory;

      setUp(() async {
        fs = MemoryFileSystem.test(
          style: platform.isWindows ? FileSystemStyle.windows : FileSystemStyle.posix,
        );
        processManager = FakeProcessManager.list(<FakeCommand>[]);
        tempDirectory = fs.systemTempDirectory.createTempSync('test_temp.');
      });

      test('succeeds on first try', () async {
        final calls = <String, List<ProcessResult>?>{
          '$gsutilCall -- stat $gsPath': <ProcessResult>[
            ProcessResult(0, 0, 'Generation: 12345', ''),
          ],
          '$gsutilCall -- cp $gsPath#12345 ${fs.path.join(tempDirectory.path, "downloaded.json")}':
              null,
          '$gsutilCall -- -h x-goog-if-generation-match:12345 cp ${fs.path.join(tempDirectory.path, "upload.json")} $gsPath':
              null,
        };
        processManager.addCommands(convertResults(calls));

        fs.file(fs.path.join(tempDirectory.path, 'downloaded.json')).createSync(recursive: true);
        fs
            .file(fs.path.join(tempDirectory.path, 'downloaded.json'))
            .writeAsStringSync('{"releases": []}');

        await transactionalUpdate(
          gsPath: gsPath,
          fs: fs,
          tempDirectory: tempDirectory,
          runGsUtil: (List<String> args) async {
            final runner = ProcessRunner(
              processManager: processManager,
              platform: platform,
              subprocessOutput: false,
            );
            return runner.runProcess(<String>[
              'python3',
              if (platform.isWindows)
                path.join('D:', 'depot_tools', 'gsutil.py')
              else
                path.join('/', 'depot_tools', 'gsutil.py'),
              '--',
              ...args,
            ]);
          },
          callback: (String contents) async {
            return '{"releases": [{"version": "1.0.0"}]}';
          },
        );
        expect(processManager.hasRemainingExpectations, isFalse);
      });

      test('assumes generation 0 if stat fails', () async {
        final String gsutilScript = platform.isWindows
            ? path.join('D:', 'depot_tools', 'gsutil.py')
            : path.join('/', 'depot_tools', 'gsutil.py');

        final commands = <FakeCommand>[
          FakeCommand(
            command: <String>['python3', gsutilScript, '--', 'stat', gsPath],
            exitCode: 1,
            stderr: 'No such object',
          ),
          FakeCommand(
            command: <String>[
              'python3',
              gsutilScript,
              '--',
              '-h',
              'x-goog-if-generation-match:0',
              'cp',
              fs.path.join(tempDirectory.path, 'upload.json'),
              gsPath,
            ],
          ),
        ];
        processManager.addCommands(commands);

        await transactionalUpdate(
          gsPath: gsPath,
          fs: fs,
          tempDirectory: tempDirectory,
          runGsUtil: (List<String> args) async {
            final runner = ProcessRunner(
              processManager: processManager,
              platform: platform,
              subprocessOutput: false,
            );
            return runner.runProcess(<String>[
              'python3',
              if (platform.isWindows)
                path.join('D:', 'depot_tools', 'gsutil.py')
              else
                path.join('/', 'depot_tools', 'gsutil.py'),
              '--',
              ...args,
            ]);
          },
          callback: (String contents) async {
            expect(contents, equals(''));
            return '{"releases": [{"version": "1.0.0"}]}';
          },
        );
        expect(processManager.hasRemainingExpectations, isFalse);
      });

      test('short-circuits on dryRun', () async {
        var callbackCalled = false;
        await transactionalUpdate(
          gsPath: gsPath,
          fs: fs,
          tempDirectory: tempDirectory,
          dryRun: true,
          runGsUtil: (List<String> args) async {
            fail('runGsUtil should not be called');
          },
          callback: (String contents) async {
            callbackCalled = true;
            expect(contents, equals(''));
            return '{"releases": [{"version": "1.0.0"}]}';
          },
        );
        expect(callbackCalled, isTrue);
      });

      test('retries on upload failure', () async {
        final String gsutilScript = platform.isWindows
            ? path.join('D:', 'depot_tools', 'gsutil.py')
            : path.join('/', 'depot_tools', 'gsutil.py');

        final commands = <FakeCommand>[
          FakeCommand(
            command: <String>['python3', gsutilScript, '--', 'stat', gsPath],
            stdout: 'Generation: 12345',
          ),
          FakeCommand(
            command: <String>[
              'python3',
              gsutilScript,
              '--',
              'cp',
              '$gsPath#12345',
              fs.path.join(tempDirectory.path, 'downloaded.json'),
            ],
          ),
          FakeCommand(
            command: <String>[
              'python3',
              gsutilScript,
              '--',
              '-h',
              'x-goog-if-generation-match:12345',
              'cp',
              fs.path.join(tempDirectory.path, 'upload.json'),
              gsPath,
            ],
            exitCode: 1,
            stderr: '412 Precondition Failed',
          ),
          FakeCommand(
            command: <String>['python3', gsutilScript, '--', 'stat', gsPath],
            stdout: 'Generation: 67890',
          ),
          FakeCommand(
            command: <String>[
              'python3',
              gsutilScript,
              '--',
              'cp',
              '$gsPath#67890',
              fs.path.join(tempDirectory.path, 'downloaded.json'),
            ],
          ),
          FakeCommand(
            command: <String>[
              'python3',
              gsutilScript,
              '--',
              '-h',
              'x-goog-if-generation-match:67890',
              'cp',
              fs.path.join(tempDirectory.path, 'upload.json'),
              gsPath,
            ],
          ),
        ];
        processManager.addCommands(commands);

        fs.file(fs.path.join(tempDirectory.path, 'downloaded.json')).createSync(recursive: true);
        fs
            .file(fs.path.join(tempDirectory.path, 'downloaded.json'))
            .writeAsStringSync('{"releases": []}');

        var callbackCount = 0;
        await transactionalUpdate(
          gsPath: gsPath,
          fs: fs,
          tempDirectory: tempDirectory,
          runGsUtil: (List<String> args) async {
            final runner = ProcessRunner(
              processManager: processManager,
              platform: platform,
              subprocessOutput: false,
            );
            return runner.runProcess(<String>[
              'python3',
              if (platform.isWindows)
                path.join('D:', 'depot_tools', 'gsutil.py')
              else
                path.join('/', 'depot_tools', 'gsutil.py'),
              '--',
              ...args,
            ]);
          },
          callback: (String contents) async {
            callbackCount++;
            return '{"releases": [{"version": "$callbackCount.0.0"}]}';
          },
        );
        expect(processManager.hasRemainingExpectations, isFalse);
        expect(callbackCount, equals(2));
      });
    });
  }
}

/// Converts a map of command lines to their results into [FakeCommand]s.
///
/// If [environment] is given, each command is additionally expected to run with
/// exactly that environment.
List<FakeCommand> convertResults(
  Map<String, List<ProcessResult>?> results, {
  Map<String, String>? environment,
}) {
  final commands = <FakeCommand>[];
  for (final String key in results.keys) {
    final List<ProcessResult>? candidates = results[key];
    final List<String> args = key.split(' ');
    if (candidates == null) {
      commands.add(FakeCommand(command: args, environment: environment));
    } else {
      for (final ProcessResult result in candidates) {
        commands.add(
          FakeCommand(
            command: args,
            environment: environment,
            exitCode: result.exitCode,
            stderr: result.stderr.toString(),
            stdout: result.stdout.toString(),
          ),
        );
      }
    }
  }
  return commands;
}
