// 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 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/base/time.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/version.dart';
import 'package:test/fake.dart';

import '../src/common.dart';
import '../src/context.dart';
import '../src/fake_process_manager.dart';

final SystemClock _testClock = SystemClock.fixed(DateTime(2015));
final DateTime _stampUpToDate = _testClock.ago(VersionFreshnessValidator.checkAgeConsideredUpToDate ~/ 2);
final DateTime _stampOutOfDate = _testClock.ago(VersionFreshnessValidator.checkAgeConsideredUpToDate * 2);

void main() {
  late FakeCache cache;
  late FakeProcessManager processManager;

  setUp(() {
    processManager = FakeProcessManager.empty();
    cache = FakeCache();
  });

  testUsingContext('Channel enum and string transform to each other', () {
    for (final Channel channel in Channel.values) {
      expect(getNameForChannel(channel), kOfficialChannels.toList()[channel.index]);
    }
    expect(kOfficialChannels.toList().map((String str) => getChannelForName(str)).toList(),
      Channel.values);
  });

  for (final String channel in kOfficialChannels) {
    DateTime getChannelUpToDateVersion() {
      return _testClock.ago(VersionFreshnessValidator.versionAgeConsideredUpToDate(channel) ~/ 2);
    }

    DateTime getChannelOutOfDateVersion() {
      return _testClock.ago(VersionFreshnessValidator.versionAgeConsideredUpToDate(channel) * 2);
    }

    group('$FlutterVersion for $channel', () {
      setUpAll(() {
        Cache.disableLocking();
        VersionFreshnessValidator.timeToPauseToLetUserReadTheMessage = Duration.zero;
      });

      testUsingContext('prints nothing when Flutter installation looks fresh', () async {
        const String flutterUpstreamUrl = 'https://github.com/flutter/flutter.git';
        processManager.addCommands(<FakeCommand>[
          const FakeCommand(
            command: <String>['git', '-c', 'log.showSignature=false', 'log', '-n', '1', '--pretty=format:%H'],
            stdout: '1234abcd',
          ),
          const FakeCommand(
            command: <String>['git', 'tag', '--points-at', '1234abcd'],
          ),
          const FakeCommand(
            command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', '1234abcd'],
            stdout: '0.1.2-3-1234abcd',
          ),
          FakeCommand(
            command: const <String>['git', 'rev-parse', '--abbrev-ref', '--symbolic', '@{upstream}'],
            stdout: 'origin/$channel',
          ),
          const FakeCommand(
            command: <String>['git', 'ls-remote', '--get-url', 'origin'],
            stdout: flutterUpstreamUrl,
          ),
          FakeCommand(
            command: const <String>['git', '-c', 'log.showSignature=false', 'log', 'HEAD', '-n', '1', '--pretty=format:%ad', '--date=iso'],
            stdout: getChannelUpToDateVersion().toString(),
          ),
          const FakeCommand(
            command: <String>['git', 'fetch', '--tags'],
          ),
          FakeCommand(
            command: const <String>['git', '-c', 'log.showSignature=false', 'log', '@{upstream}', '-n', '1', '--pretty=format:%ad', '--date=iso'],
            stdout: getChannelOutOfDateVersion().toString(),
          ),
          const FakeCommand(
            command: <String>['git', '-c', 'log.showSignature=false', 'log', '-n', '1', '--pretty=format:%ar'],
            stdout: '1 second ago',
          ),
          FakeCommand(
            command: const <String>['git', '-c', 'log.showSignature=false', 'log', 'HEAD', '-n', '1', '--pretty=format:%ad', '--date=iso'],
            stdout: getChannelUpToDateVersion().toString(),
          ),
          FakeCommand(
            command: const <String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
            stdout: channel,
          ),
        ]);

        final FlutterVersion flutterVersion = globals.flutterVersion;
        await flutterVersion.checkFlutterVersionFreshness();
        expect(flutterVersion.channel, channel);
        expect(flutterVersion.repositoryUrl, flutterUpstreamUrl);
        expect(flutterVersion.frameworkRevision, '1234abcd');
        expect(flutterVersion.frameworkRevisionShort, '1234abcd');
        expect(flutterVersion.frameworkVersion, '0.0.0-unknown');
        expect(
          flutterVersion.toString(),
          'Flutter • channel $channel • $flutterUpstreamUrl\n'
          'Framework • revision 1234abcd (1 second ago) • ${getChannelUpToDateVersion()}\n'
          'Engine • revision abcdefg\n'
          'Tools • Dart 2.12.0 • DevTools 2.8.0',
        );
        expect(flutterVersion.frameworkAge, '1 second ago');
        expect(flutterVersion.getVersionString(), '$channel/1234abcd');
        expect(flutterVersion.getBranchName(), channel);
        expect(flutterVersion.getVersionString(redactUnknownBranches: true), '$channel/1234abcd');
        expect(flutterVersion.getBranchName(redactUnknownBranches: true), channel);

        expect(testLogger.statusText, isEmpty);
        expect(processManager, hasNoRemainingExpectations);
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(clock: _testClock),
        ProcessManager: () => processManager,
        Cache: () => cache,
      });

      testWithoutContext('prints nothing when Flutter installation looks out-of-date but is actually up-to-date', () async {
        final FakeFlutterVersion flutterVersion = FakeFlutterVersion(channel: channel);
        final BufferLogger logger = BufferLogger.test();
        final VersionCheckStamp stamp = VersionCheckStamp(
          lastTimeVersionWasChecked: _stampOutOfDate,
          lastKnownRemoteVersion: getChannelOutOfDateVersion(),
        );
        cache.versionStamp = json.encode(stamp);

        await VersionFreshnessValidator(
          version: flutterVersion,
          cache: cache,
          clock: _testClock,
          logger: logger,
          localFrameworkCommitDate: getChannelOutOfDateVersion(),
          latestFlutterCommitDate: getChannelOutOfDateVersion(),
        ).run();

        expect(logger.statusText, isEmpty);
      });

      testWithoutContext('does not ping server when version stamp is up-to-date', () async {
        final FakeFlutterVersion flutterVersion = FakeFlutterVersion(channel: channel);
        final BufferLogger logger = BufferLogger.test();
        final VersionCheckStamp stamp = VersionCheckStamp(
          lastTimeVersionWasChecked: _stampUpToDate,
          lastKnownRemoteVersion: getChannelUpToDateVersion(),
        );
        cache.versionStamp = json.encode(stamp);

        await VersionFreshnessValidator(
          version: flutterVersion,
          cache: cache,
          clock: _testClock,
          logger: logger,
          localFrameworkCommitDate: getChannelOutOfDateVersion(),
          latestFlutterCommitDate: getChannelUpToDateVersion(),
        ).run();

        expect(logger.statusText, contains('A new version of Flutter is available!'));
        expect(cache.setVersionStamp, true);
      });

      testWithoutContext('does not print warning if printed recently', () async {
        final FakeFlutterVersion flutterVersion = FakeFlutterVersion(channel: channel);
        final BufferLogger logger = BufferLogger.test();
        final VersionCheckStamp stamp = VersionCheckStamp(
          lastTimeVersionWasChecked: _stampUpToDate,
          lastKnownRemoteVersion: getChannelUpToDateVersion(),
          lastTimeWarningWasPrinted: _testClock.now(),
        );
        cache.versionStamp = json.encode(stamp);

        await VersionFreshnessValidator(
          version: flutterVersion,
          cache: cache,
          clock: _testClock,
          logger: logger,
          localFrameworkCommitDate: getChannelOutOfDateVersion(),
          latestFlutterCommitDate: getChannelUpToDateVersion(),
        ).run();

        expect(logger.statusText, isEmpty);
      });

      testWithoutContext('pings server when version stamp is missing', () async {
        final FakeFlutterVersion flutterVersion = FakeFlutterVersion(channel: channel);
        final BufferLogger logger = BufferLogger.test();
        cache.versionStamp = '{}';

        await VersionFreshnessValidator(
          version: flutterVersion,
          cache: cache,
          clock: _testClock,
          logger: logger,
          localFrameworkCommitDate: getChannelOutOfDateVersion(),
          latestFlutterCommitDate: getChannelUpToDateVersion(),
        ).run();

        expect(logger.statusText, contains('A new version of Flutter is available!'));
        expect(cache.setVersionStamp, true);
      });

      testWithoutContext('pings server when version stamp is out-of-date', () async {
        final FakeFlutterVersion flutterVersion = FakeFlutterVersion(channel: channel);
        final BufferLogger logger = BufferLogger.test();
        final VersionCheckStamp stamp = VersionCheckStamp(
          lastTimeVersionWasChecked: _stampOutOfDate,
          lastKnownRemoteVersion: _testClock.ago(const Duration(days: 2)),
        );
        cache.versionStamp = json.encode(stamp);

        await VersionFreshnessValidator(
          version: flutterVersion,
          cache: cache,
          clock: _testClock,
          logger: logger,
          localFrameworkCommitDate: getChannelOutOfDateVersion(),
          latestFlutterCommitDate: getChannelUpToDateVersion(),
        ).run();

        expect(logger.statusText, contains('A new version of Flutter is available!'));
      });

      testWithoutContext('does not print warning when unable to connect to server if not out of date', () async {
        final FakeFlutterVersion flutterVersion = FakeFlutterVersion(channel: channel);
        final BufferLogger logger = BufferLogger.test();
        cache.versionStamp = '{}';

        await VersionFreshnessValidator(
          version: flutterVersion,
          cache: cache,
          clock: _testClock,
          logger: logger,
          localFrameworkCommitDate: getChannelUpToDateVersion(),
          // latestFlutterCommitDate defaults to null because we failed to get remote version
        ).run();

        expect(logger.statusText, isEmpty);
      });

      testWithoutContext('prints warning when unable to connect to server if really out of date', () async {
        final FakeFlutterVersion flutterVersion = FakeFlutterVersion(channel: channel);
        final BufferLogger logger = BufferLogger.test();
        final VersionCheckStamp stamp = VersionCheckStamp(
          lastTimeVersionWasChecked: _stampOutOfDate,
          lastKnownRemoteVersion: _testClock.ago(const Duration(days: 2)),
        );
        cache.versionStamp = json.encode(stamp);

        await VersionFreshnessValidator(
          version: flutterVersion,
          cache: cache,
          clock: _testClock,
          logger: logger,
          localFrameworkCommitDate: getChannelOutOfDateVersion(),
          // latestFlutterCommitDate defaults to null because we failed to get remote version
        ).run();

        final Duration frameworkAge = _testClock.now().difference(getChannelOutOfDateVersion());
        expect(logger.statusText, contains('WARNING: your installation of Flutter is ${frameworkAge.inDays} days old.'));
      });

      group('$VersionCheckStamp for $channel', () {
        void expectDefault(VersionCheckStamp stamp) {
          expect(stamp.lastKnownRemoteVersion, isNull);
          expect(stamp.lastTimeVersionWasChecked, isNull);
          expect(stamp.lastTimeWarningWasPrinted, isNull);
        }

        testWithoutContext('loads blank when stamp file missing', () async {
          cache.versionStamp = null;

          expectDefault(await VersionCheckStamp.load(cache, BufferLogger.test()));
        });

        testWithoutContext('loads blank when stamp file is malformed JSON', () async {
          cache.versionStamp = '<';

          expectDefault(await VersionCheckStamp.load(cache, BufferLogger.test()));
        });

        testWithoutContext('loads blank when stamp file is well-formed but invalid JSON', () async {
          cache.versionStamp = '[]';

          expectDefault(await VersionCheckStamp.load(cache, BufferLogger.test()));
        });

        testWithoutContext('loads valid JSON', () async {
          final String value = '''
        {
          "lastKnownRemoteVersion": "${_testClock.ago(const Duration(days: 1))}",
          "lastTimeVersionWasChecked": "${_testClock.ago(const Duration(days: 2))}",
          "lastTimeWarningWasPrinted": "${_testClock.now()}"
        }
        ''';
          cache.versionStamp = value;

          final VersionCheckStamp stamp = await VersionCheckStamp.load(cache, BufferLogger.test());

          expect(stamp.lastKnownRemoteVersion, _testClock.ago(const Duration(days: 1)));
          expect(stamp.lastTimeVersionWasChecked, _testClock.ago(const Duration(days: 2)));
          expect(stamp.lastTimeWarningWasPrinted, _testClock.now());
        });
      });
    });
  }

    group('VersionUpstreamValidator', () {
      const String flutterStandardUrlDotGit = 'https://github.com/flutter/flutter.git';
      const String flutterNonStandardUrlDotGit = 'https://githubmirror.com/flutter/flutter.git';
      const String flutterStandardSshUrlDotGit = 'git@github.com:flutter/flutter.git';

      VersionCheckError? runUpstreamValidator({
        String? versionUpstreamUrl,
        String? flutterGitUrl,
      }){
        final Platform testPlatform = FakePlatform(environment: <String, String> {
          if (flutterGitUrl != null) 'FLUTTER_GIT_URL': flutterGitUrl,
        });
        return VersionUpstreamValidator(
          version: FakeFlutterVersion(repositoryUrl: versionUpstreamUrl, channel: 'master'),
          platform: testPlatform,
        ).run();
      }

      testWithoutContext('returns error if repository url is null', () {
        final VersionCheckError error = runUpstreamValidator(
          // repositoryUrl is null by default
        )!;
        expect(error, isNotNull);
        expect(
          error.message,
          contains('The tool could not determine the remote upstream which is being tracked by the SDK.'),
        );
      });

      testWithoutContext('does not return error at standard remote url with FLUTTER_GIT_URL unset', () {
        expect(runUpstreamValidator(versionUpstreamUrl: flutterStandardUrlDotGit), isNull);
      });

      testWithoutContext('returns error at non-standard remote url with FLUTTER_GIT_URL unset', () {
        final VersionCheckError error = runUpstreamValidator(versionUpstreamUrl: flutterNonStandardUrlDotGit)!;
        expect(error, isNotNull);
        expect(
          error.message,
          contains(
            'The Flutter SDK is tracking a non-standard remote "$flutterNonStandardUrlDotGit".\n'
            'Set the environment variable "FLUTTER_GIT_URL" to "$flutterNonStandardUrlDotGit". '
            'If this is intentional, it is recommended to use "git" directly to manage the SDK.'
          ),
        );
      });

      testWithoutContext('does not return error at non-standard remote url with FLUTTER_GIT_URL set', () {
        expect(runUpstreamValidator(
          versionUpstreamUrl: flutterNonStandardUrlDotGit,
          flutterGitUrl: flutterNonStandardUrlDotGit,
        ), isNull);
      });

      testWithoutContext('respects FLUTTER_GIT_URL even if upstream remote url is standard', () {
        final VersionCheckError error = runUpstreamValidator(
            versionUpstreamUrl: flutterStandardUrlDotGit,
            flutterGitUrl: flutterNonStandardUrlDotGit,
        )!;
        expect(error, isNotNull);
        expect(
          error.message,
          contains(
            'The Flutter SDK is tracking "$flutterStandardUrlDotGit" but "FLUTTER_GIT_URL" is set to "$flutterNonStandardUrlDotGit".\n'
            'Either remove "FLUTTER_GIT_URL" from the environment or set it to "$flutterStandardUrlDotGit". '
            'If this is intentional, it is recommended to use "git" directly to manage the SDK.'
          ),
        );
      });

      testWithoutContext('does not return error at standard ssh url with FLUTTER_GIT_URL unset', () {
        expect(runUpstreamValidator(versionUpstreamUrl: flutterStandardSshUrlDotGit), isNull);
      });

      testWithoutContext('stripDotGit removes ".git" suffix if any', () {
        expect(VersionUpstreamValidator.stripDotGit('https://github.com/flutter/flutter.git'), 'https://github.com/flutter/flutter');
        expect(VersionUpstreamValidator.stripDotGit('https://github.com/flutter/flutter'), 'https://github.com/flutter/flutter');
        expect(VersionUpstreamValidator.stripDotGit('git@github.com:flutter/flutter.git'), 'git@github.com:flutter/flutter');
        expect(VersionUpstreamValidator.stripDotGit('git@github.com:flutter/flutter'), 'git@github.com:flutter/flutter');
        expect(VersionUpstreamValidator.stripDotGit('https://githubmirror.com/flutter/flutter.git.git'), 'https://githubmirror.com/flutter/flutter.git');
        expect(VersionUpstreamValidator.stripDotGit('https://githubmirror.com/flutter/flutter.gitgit'), 'https://githubmirror.com/flutter/flutter.gitgit');
      });
    });

  testUsingContext('version handles unknown branch', () async {
    processManager.addCommands(<FakeCommand>[
      const FakeCommand(
        command: <String>['git', '-c', 'log.showSignature=false', 'log', '-n', '1', '--pretty=format:%H'],
        stdout: '1234abcd',
      ),
      const FakeCommand(
        command: <String>['git', 'tag', '--points-at', '1234abcd'],
      ),
      const FakeCommand(
        command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', '1234abcd'],
        stdout: '0.1.2-3-1234abcd',
      ),
      const FakeCommand(
        command: <String>['git', 'rev-parse', '--abbrev-ref', '--symbolic', '@{upstream}'],
        stdout: 'feature-branch',
      ),
      const FakeCommand(
        command: <String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
        stdout: 'feature-branch',
      ),
    ]);

    final FlutterVersion flutterVersion = globals.flutterVersion;
    expect(flutterVersion.channel, 'feature-branch');
    expect(flutterVersion.getVersionString(), 'feature-branch/1234abcd');
    expect(flutterVersion.getBranchName(), 'feature-branch');
    expect(flutterVersion.getVersionString(redactUnknownBranches: true), '[user-branch]/1234abcd');
    expect(flutterVersion.getBranchName(redactUnknownBranches: true), '[user-branch]');
    expect(processManager, hasNoRemainingExpectations);
  }, overrides: <Type, Generator>{
    FlutterVersion: () => FlutterVersion(clock: _testClock),
    ProcessManager: () => processManager,
    Cache: () => cache,
  });

  testUsingContext('GitTagVersion', () {
    const String hash = 'abcdef';
    GitTagVersion gitTagVersion;

    // Master channel
    gitTagVersion = GitTagVersion.parse('1.2.0-4.5.pre-13-g$hash');
    expect(gitTagVersion.frameworkVersionFor(hash), '1.2.0-5.0.pre.13');
    expect(gitTagVersion.gitTag, '1.2.0-4.5.pre');
    expect(gitTagVersion.devVersion, 4);
    expect(gitTagVersion.devPatch, 5);

    // Stable channel
    gitTagVersion = GitTagVersion.parse('1.2.3');
    expect(gitTagVersion.frameworkVersionFor(hash), '1.2.3');
    expect(gitTagVersion.x, 1);
    expect(gitTagVersion.y, 2);
    expect(gitTagVersion.z, 3);
    expect(gitTagVersion.devVersion, null);
    expect(gitTagVersion.devPatch, null);

    // Dev channel
    gitTagVersion = GitTagVersion.parse('1.2.3-4.5.pre');
    expect(gitTagVersion.frameworkVersionFor(hash), '1.2.3-4.5.pre');
    expect(gitTagVersion.gitTag, '1.2.3-4.5.pre');
    expect(gitTagVersion.devVersion, 4);
    expect(gitTagVersion.devPatch, 5);

    gitTagVersion = GitTagVersion.parse('1.2.3-13-g$hash');
    expect(gitTagVersion.frameworkVersionFor(hash), '1.2.4-0.0.pre.13');
    expect(gitTagVersion.gitTag, '1.2.3');
    expect(gitTagVersion.devVersion, null);
    expect(gitTagVersion.devPatch, null);

    // new tag release format, dev channel
    gitTagVersion = GitTagVersion.parse('1.2.3-4.5.pre-0-g$hash');
    expect(gitTagVersion.frameworkVersionFor(hash), '1.2.3-4.5.pre');
    expect(gitTagVersion.gitTag, '1.2.3-4.5.pre');
    expect(gitTagVersion.devVersion, 4);
    expect(gitTagVersion.devPatch, 5);

    // new tag release format, stable channel
    gitTagVersion = GitTagVersion.parse('1.2.3-13-g$hash');
    expect(gitTagVersion.frameworkVersionFor(hash), '1.2.4-0.0.pre.13');
    expect(gitTagVersion.gitTag, '1.2.3');
    expect(gitTagVersion.devVersion, null);
    expect(gitTagVersion.devPatch, null);

    expect(GitTagVersion.parse('98.76.54-32-g$hash').frameworkVersionFor(hash), '98.76.55-0.0.pre.32');
    expect(GitTagVersion.parse('10.20.30-0-g$hash').frameworkVersionFor(hash), '10.20.30');
    expect(testLogger.traceText, '');
    expect(GitTagVersion.parse('v1.2.3+hotfix.1-4-g$hash').frameworkVersionFor(hash), '0.0.0-unknown');
    expect(GitTagVersion.parse('x1.2.3-4-g$hash').frameworkVersionFor(hash), '0.0.0-unknown');
    expect(GitTagVersion.parse('1.0.0-unknown-0-g$hash').frameworkVersionFor(hash), '0.0.0-unknown');
    expect(GitTagVersion.parse('beta-1-g$hash').frameworkVersionFor(hash), '0.0.0-unknown');
    expect(GitTagVersion.parse('1.2.3-4-gx$hash').frameworkVersionFor(hash), '0.0.0-unknown');
    expect(testLogger.statusText, '');
    expect(testLogger.errorText, '');
    expect(
      testLogger.traceText,
      'Could not interpret results of "git describe": v1.2.3+hotfix.1-4-gabcdef\n'
      'Could not interpret results of "git describe": x1.2.3-4-gabcdef\n'
      'Could not interpret results of "git describe": 1.0.0-unknown-0-gabcdef\n'
      'Could not interpret results of "git describe": beta-1-gabcdef\n'
      'Could not interpret results of "git describe": 1.2.3-4-gxabcdef\n',
    );
  });

  testUsingContext('determine reports correct stable version if HEAD is at a tag', () {
    const String stableTag = '1.2.3';
    final FakeProcessManager fakeProcessManager = FakeProcessManager.list(
      <FakeCommand>[
        const FakeCommand(
          command: <String>['git', 'tag', '--points-at', 'HEAD'],
          stdout: stableTag,
        ),
      ],
    );
    final ProcessUtils processUtils = ProcessUtils(
      processManager: fakeProcessManager,
      logger: BufferLogger.test(),
    );
    final FakePlatform platform = FakePlatform();
    final GitTagVersion gitTagVersion = GitTagVersion.determine(processUtils, platform, workingDirectory: '.');
    expect(gitTagVersion.frameworkVersionFor('abcd1234'), stableTag);
  });

  testUsingContext('determine favors stable tag over dev tag if both identify HEAD', () {
    const String stableTag = '1.2.3';
    final FakeProcessManager fakeProcessManager = FakeProcessManager.list(
      <FakeCommand>[
        const FakeCommand(
          command: <String>['git', 'tag', '--points-at', 'HEAD'],
          // This tests the unlikely edge case where a dev release made it to stable without any cherry picks
          stdout: '1.2.3-6.0.pre\n$stableTag',
        ),
      ],
    );
    final ProcessUtils processUtils = ProcessUtils(
      processManager: fakeProcessManager,
      logger: BufferLogger.test(),
    );
    final FakePlatform platform = FakePlatform();

    final GitTagVersion gitTagVersion = GitTagVersion.determine(processUtils, platform, workingDirectory: '.');
    expect(gitTagVersion.frameworkVersionFor('abcd1234'), stableTag);
  });

  testUsingContext('determine reports correct git describe version if HEAD is not at a tag', () {
    const String devTag = '1.2.0-2.0.pre';
    const String headRevision = 'abcd1234';
    const String commitsAhead = '12';
    final FakeProcessManager fakeProcessManager = FakeProcessManager.list(
      <FakeCommand>[
        const FakeCommand(
          command: <String>['git', 'tag', '--points-at', 'HEAD'],
          // no output, since there's no tag
        ),
        const FakeCommand(
          command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
          stdout: '$devTag-$commitsAhead-g$headRevision',
        ),
      ],
    );
    final ProcessUtils processUtils = ProcessUtils(
      processManager: fakeProcessManager,
      logger: BufferLogger.test(),
    );
    final FakePlatform platform = FakePlatform();

    final GitTagVersion gitTagVersion = GitTagVersion.determine(processUtils, platform, workingDirectory: '.');
    // reported version should increment the m
    expect(gitTagVersion.frameworkVersionFor(headRevision), '1.2.0-3.0.pre.12');
  });

  testUsingContext('determine does not call fetch --tags', () {
    final FakeProcessManager fakeProcessManager = FakeProcessManager.list(<FakeCommand>[
      const FakeCommand(
        command: <String>['git', 'tag', '--points-at', 'HEAD'],
      ),
      const FakeCommand(
        command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
        stdout: 'v0.1.2-3-1234abcd',
      ),
    ]);
    final ProcessUtils processUtils = ProcessUtils(
      processManager: fakeProcessManager,
      logger: BufferLogger.test(),
    );
    final FakePlatform platform = FakePlatform();

    GitTagVersion.determine(processUtils, platform, workingDirectory: '.');
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testUsingContext('determine does not fetch tags on dev/stable/beta', () {
    final FakeProcessManager fakeProcessManager = FakeProcessManager.list(<FakeCommand>[
      const FakeCommand(
        command: <String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
        stdout: 'dev',
      ),
      const FakeCommand(
        command: <String>['git', 'tag', '--points-at', 'HEAD'],
      ),
      const FakeCommand(
        command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
        stdout: 'v0.1.2-3-1234abcd',
      ),
    ]);
    final ProcessUtils processUtils = ProcessUtils(
      processManager: fakeProcessManager,
      logger: BufferLogger.test(),
    );
    final FakePlatform platform = FakePlatform();

    GitTagVersion.determine(processUtils, platform, workingDirectory: '.', fetchTags: true);
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testUsingContext('determine calls fetch --tags on master', () {
    final FakeProcessManager fakeProcessManager = FakeProcessManager.list(<FakeCommand>[
      const FakeCommand(
        command: <String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
        stdout: 'master',
      ),
      const FakeCommand(
        command: <String>['git', 'fetch', 'https://github.com/flutter/flutter.git', '--tags', '-f'],
      ),
      const FakeCommand(
        command: <String>['git', 'tag', '--points-at', 'HEAD'],
      ),
      const FakeCommand(
        command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
        stdout: 'v0.1.2-3-1234abcd',
      ),
    ]);
    final ProcessUtils processUtils = ProcessUtils(
      processManager: fakeProcessManager,
      logger: BufferLogger.test(),
    );
    final FakePlatform platform = FakePlatform();

    GitTagVersion.determine(processUtils, platform, workingDirectory: '.', fetchTags: true);
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });

  testUsingContext('determine uses overridden git url', () {
    final FakeProcessManager fakeProcessManager = FakeProcessManager.list(<FakeCommand>[
      const FakeCommand(
        command: <String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
        stdout: 'master',
      ),
      const FakeCommand(
        command: <String>['git', 'fetch', 'https://githubmirror.com/flutter.git', '--tags', '-f'],
      ),
      const FakeCommand(
        command: <String>['git', 'tag', '--points-at', 'HEAD'],
      ),
      const FakeCommand(
        command: <String>['git', 'describe', '--match', '*.*.*', '--long', '--tags', 'HEAD'],
        stdout: 'v0.1.2-3-1234abcd',
      ),
    ]);
    final ProcessUtils processUtils = ProcessUtils(
      processManager: fakeProcessManager,
      logger: BufferLogger.test(),
    );
    final FakePlatform platform = FakePlatform(
      environment: <String, String> {'FLUTTER_GIT_URL': 'https://githubmirror.com/flutter.git'},
    );

    GitTagVersion.determine(processUtils, platform, workingDirectory: '.', fetchTags: true);
    expect(fakeProcessManager, hasNoRemainingExpectations);
  });
}

class FakeCache extends Fake implements Cache {
  String? versionStamp;
  bool setVersionStamp = false;

  @override
  String get engineRevision => 'abcdefg';

  @override
  String get devToolsVersion => '2.8.0';

  @override
  String get dartSdkVersion => '2.12.0';

  @override
  void checkLockAcquired() { }

  @override
  String? getStampFor(String artifactName) {
    if (artifactName == VersionCheckStamp.flutterVersionCheckStampFile) {
      return versionStamp;
    }
    return null;
  }

  @override
  void setStampFor(String artifactName, String version) {
    if (artifactName == VersionCheckStamp.flutterVersionCheckStampFile) {
      setVersionStamp = true;
    }
  }
}

class FakeFlutterVersion extends Fake implements FlutterVersion {
  FakeFlutterVersion({required this.channel, this.repositoryUrl});

  @override
  final String channel;

  @override
  final String? repositoryUrl;
}
