// 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:collection/collection.dart' show ListEquality;
import 'package:flutter_tools/src/base/context.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/process.dart';
import 'package:flutter_tools/src/base/time.dart';
import 'package:flutter_tools/src/base/utils.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:mockito/mockito.dart';
import 'package:process/process.dart';

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

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

void main() {
  MockProcessManager mockProcessManager;
  MockCache mockCache;

  setUp(() {
    mockProcessManager = MockProcessManager();
    mockCache = MockCache();
  });

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

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

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

      testUsingContext('prints nothing when Flutter installation looks fresh', () async {
        fakeData(
          mockProcessManager,
          mockCache,
          localCommitDate: getChannelUpToDateVersion(),
          // Server will be pinged because we haven't pinged within last x days
          expectServerPing: true,
          remoteCommitDate: getChannelOutOfDateVersion(),
          expectSetStamp: true,
          channel: channel,
        );
        await globals.flutterVersion.checkFlutterVersionFreshness();
        _expectVersionMessage('');
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });

      testUsingContext('prints nothing when Flutter installation looks out-of-date but is actually up-to-date', () async {
        fakeData(
          mockProcessManager,
          mockCache,
          localCommitDate: getChannelOutOfDateVersion(),
          stamp: VersionCheckStamp(
            lastTimeVersionWasChecked: _stampOutOfDate,
            lastKnownRemoteVersion: getChannelOutOfDateVersion(),
          ),
          remoteCommitDate: getChannelOutOfDateVersion(),
          expectSetStamp: true,
          expectServerPing: true,
          channel: channel,
        );
        final FlutterVersion version = globals.flutterVersion;

        await version.checkFlutterVersionFreshness();
        _expectVersionMessage('');
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });

      testUsingContext('does not ping server when version stamp is up-to-date', () async {
        fakeData(
          mockProcessManager,
          mockCache,
          localCommitDate: getChannelOutOfDateVersion(),
          stamp: VersionCheckStamp(
            lastTimeVersionWasChecked: _stampUpToDate,
            lastKnownRemoteVersion: getChannelUpToDateVersion(),
          ),
          expectSetStamp: true,
          channel: channel,
        );

        final FlutterVersion version = globals.flutterVersion;
        await version.checkFlutterVersionFreshness();
        _expectVersionMessage(FlutterVersion.newVersionAvailableMessage());
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });

      testUsingContext('does not print warning if printed recently', () async {
        fakeData(
          mockProcessManager,
          mockCache,
          localCommitDate: getChannelOutOfDateVersion(),
          stamp: VersionCheckStamp(
            lastTimeVersionWasChecked: _stampUpToDate,
            lastKnownRemoteVersion: getChannelUpToDateVersion(),
          ),
          expectSetStamp: true,
          channel: channel,
        );

        final FlutterVersion version = globals.flutterVersion;
        await version.checkFlutterVersionFreshness();
        _expectVersionMessage(FlutterVersion.newVersionAvailableMessage());
        expect((await VersionCheckStamp.load()).lastTimeWarningWasPrinted, _testClock.now());

        await version.checkFlutterVersionFreshness();
        _expectVersionMessage('');
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });

      testUsingContext('pings server when version stamp is missing then does not', () async {
        fakeData(
          mockProcessManager,
          mockCache,
          localCommitDate: getChannelOutOfDateVersion(),
          remoteCommitDate: getChannelUpToDateVersion(),
          expectSetStamp: true,
          expectServerPing: true,
          channel: channel,
        );
        final FlutterVersion version = globals.flutterVersion;

        await version.checkFlutterVersionFreshness();
        _expectVersionMessage(FlutterVersion.newVersionAvailableMessage());

        // Immediate subsequent check is not expected to ping the server.
        fakeData(
          mockProcessManager,
          mockCache,
          localCommitDate: getChannelOutOfDateVersion(),
          stamp: await VersionCheckStamp.load(),
          channel: channel,
        );
        await version.checkFlutterVersionFreshness();
        _expectVersionMessage('');
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });

      testUsingContext('pings server when version stamp is out-of-date', () async {
        fakeData(
          mockProcessManager,
          mockCache,
          localCommitDate: getChannelOutOfDateVersion(),
          stamp: VersionCheckStamp(
            lastTimeVersionWasChecked: _stampOutOfDate,
            lastKnownRemoteVersion: _testClock.ago(const Duration(days: 2)),
          ),
          remoteCommitDate: getChannelUpToDateVersion(),
          expectSetStamp: true,
          expectServerPing: true,
          channel: channel,
        );
        final FlutterVersion version = globals.flutterVersion;

        await version.checkFlutterVersionFreshness();
        _expectVersionMessage(FlutterVersion.newVersionAvailableMessage());
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });

      testUsingContext('does not print warning when unable to connect to server if not out of date', () async {
        fakeData(
          mockProcessManager,
          mockCache,
          localCommitDate: getChannelUpToDateVersion(),
          errorOnFetch: true,
          expectServerPing: true,
          expectSetStamp: true,
          channel: channel,
        );
        final FlutterVersion version = globals.flutterVersion;

        await version.checkFlutterVersionFreshness();
        _expectVersionMessage('');
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });

      testUsingContext('prints warning when unable to connect to server if really out of date', () async {
        fakeData(
          mockProcessManager,
          mockCache,
          localCommitDate: getChannelOutOfDateVersion(),
          errorOnFetch: true,
          expectServerPing: true,
          expectSetStamp: true,
          channel: channel,
        );
        final FlutterVersion version = globals.flutterVersion;

        await version.checkFlutterVersionFreshness();
        _expectVersionMessage(FlutterVersion.versionOutOfDateMessage(_testClock.now().difference(getChannelOutOfDateVersion())));
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });

      testUsingContext('versions comparison', () async {
        fakeData(
          mockProcessManager,
          mockCache,
          localCommitDate: getChannelOutOfDateVersion(),
          errorOnFetch: true,
          expectServerPing: true,
          expectSetStamp: true,
          channel: channel,
        );
        final FlutterVersion version = globals.flutterVersion;

        when(mockProcessManager.runSync(
          <String>['git', 'merge-base', '--is-ancestor', 'abcdef', '123456'],
          workingDirectory: anyNamed('workingDirectory'),
        )).thenReturn(ProcessResult(1, 0, '', ''));

        expect(
            version.checkRevisionAncestry(
              tentativeDescendantRevision: '123456',
              tentativeAncestorRevision: 'abcdef',
            ),
            true);

        verify(mockProcessManager.runSync(
          <String>['git', 'merge-base', '--is-ancestor', 'abcdef', '123456'],
          workingDirectory: anyNamed('workingDirectory'),
        ));
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
      });
    });

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

      testUsingContext('loads blank when stamp file missing', () async {
        fakeData(mockProcessManager, mockCache, channel: channel);
        _expectDefault(await VersionCheckStamp.load());
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });

      testUsingContext('loads blank when stamp file is malformed JSON', () async {
        fakeData(mockProcessManager, mockCache, stampJson: '<', channel: channel);
        _expectDefault(await VersionCheckStamp.load());
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });

      testUsingContext('loads blank when stamp file is well-formed but invalid JSON', () async {
        fakeData(
          mockProcessManager,
          mockCache,
          stampJson: '[]',
          channel: channel,
        );
        _expectDefault(await VersionCheckStamp.load());
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });

      testUsingContext('loads valid JSON', () async {
        fakeData(
          mockProcessManager,
          mockCache,
          stampJson: '''
      {
        "lastKnownRemoteVersion": "${_testClock.ago(const Duration(days: 1))}",
        "lastTimeVersionWasChecked": "${_testClock.ago(const Duration(days: 2))}",
        "lastTimeWarningWasPrinted": "${_testClock.now()}"
      }
      ''',
          channel: channel,
        );

        final VersionCheckStamp stamp = await VersionCheckStamp.load();
        expect(stamp.lastKnownRemoteVersion, _testClock.ago(const Duration(days: 1)));
        expect(stamp.lastTimeVersionWasChecked, _testClock.ago(const Duration(days: 2)));
        expect(stamp.lastTimeWarningWasPrinted, _testClock.now());
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });

      testUsingContext('stores version stamp', () async {
        fakeData(
          mockProcessManager,
          mockCache,
          expectSetStamp: true,
          channel: channel,
        );

        _expectDefault(await VersionCheckStamp.load());

        final VersionCheckStamp stamp = VersionCheckStamp(
          lastKnownRemoteVersion: _testClock.ago(const Duration(days: 1)),
          lastTimeVersionWasChecked: _testClock.ago(const Duration(days: 2)),
          lastTimeWarningWasPrinted: _testClock.now(),
        );
        await stamp.store();

        final VersionCheckStamp storedStamp = await VersionCheckStamp.load();
        expect(storedStamp.lastKnownRemoteVersion, _testClock.ago(const Duration(days: 1)));
        expect(storedStamp.lastTimeVersionWasChecked, _testClock.ago(const Duration(days: 2)));
        expect(storedStamp.lastTimeWarningWasPrinted, _testClock.now());
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });

      testUsingContext('overwrites individual fields', () async {
        fakeData(
          mockProcessManager,
          mockCache,
          expectSetStamp: true,
          channel: channel,
        );

        _expectDefault(await VersionCheckStamp.load());

        final VersionCheckStamp stamp = VersionCheckStamp(
          lastKnownRemoteVersion: _testClock.ago(const Duration(days: 10)),
          lastTimeVersionWasChecked: _testClock.ago(const Duration(days: 9)),
          lastTimeWarningWasPrinted: _testClock.ago(const Duration(days: 8)),
        );
        await stamp.store(
          newKnownRemoteVersion: _testClock.ago(const Duration(days: 1)),
          newTimeVersionWasChecked: _testClock.ago(const Duration(days: 2)),
          newTimeWarningWasPrinted: _testClock.now(),
        );

        final VersionCheckStamp storedStamp = await VersionCheckStamp.load();
        expect(storedStamp.lastKnownRemoteVersion, _testClock.ago(const Duration(days: 1)));
        expect(storedStamp.lastTimeVersionWasChecked, _testClock.ago(const Duration(days: 2)));
        expect(storedStamp.lastTimeWarningWasPrinted, _testClock.now());
      }, overrides: <Type, Generator>{
        FlutterVersion: () => FlutterVersion(_testClock),
        ProcessManager: () => mockProcessManager,
        Cache: () => mockCache,
      });
    });
  }

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

    // Master channel
    gitTagVersion = GitTagVersion.parse('1.2.3-4.5.pre-13-g$hash');
    expect(gitTagVersion.frameworkVersionFor(hash), '1.2.3-5.0.pre.13');
    expect(gitTagVersion.gitTag, '1.2.3-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.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.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.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 favors stable tags over dev tags', () {
    final MockProcessUtils mockProcessUtils = MockProcessUtils();
    when(mockProcessUtils.runSync(
      <String>['git', 'tag', '--contains', 'HEAD'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(RunResult(
      ProcessResult(1, 0, '1.2.3-0.0.pre\n1.2.3\n1.2.3-0.1.pre', ''),
      <String>['git', 'tag', '--contains', 'HEAD'],
    ));
    final GitTagVersion version = GitTagVersion.determine(mockProcessUtils, workingDirectory: '.');
    expect(version.gitTag, '1.2.3');
    expect(version.devPatch, null);
    expect(version.devVersion, null);
    // We shouldn't have to fallback to git describe, because we are exactly
    // on a release tag.
    verifyNever(mockProcessUtils.runSync(
      <String>['git', 'describe', '--match', '*.*.*-*.*.pre', '--first-parent', '--long', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    ));
  });

  testUsingContext('determine does not call fetch --tags', () {
    final MockProcessUtils processUtils = MockProcessUtils();
    when(processUtils.runSync(
      <String>['git', 'fetch', 'https://github.com/flutter/flutter.git', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(RunResult(ProcessResult(105, 0, '', ''), <String>['git', 'fetch']));
    when(processUtils.runSync(
      <String>['git', 'describe', '--match', '*.*.*-*.*.pre', '--first-parent', '--long', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(RunResult(ProcessResult(106, 0, 'v0.1.2-3-1234abcd', ''), <String>['git', 'describe']));
    when(processUtils.runSync(
      <String>['git', 'tag', '--contains', 'HEAD'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(
      RunResult(ProcessResult(110, 0, '', ''),
      <String>['git', 'tag', '--contains', 'HEAD'],
    ));

    GitTagVersion.determine(processUtils, workingDirectory: '.');

    verifyNever(processUtils.runSync(
      <String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    ));
    verifyNever(processUtils.runSync(
      <String>['git', 'fetch', 'https://github.com/flutter/flutter.git', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    ));
    verify(processUtils.runSync(
      <String>['git', 'describe', '--match', '*.*.*-*.*.pre', '--first-parent', '--long', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).called(1);
  });

  testUsingContext('determine does not fetch tags on dev/stable/beta', () {
    final MockProcessUtils processUtils = MockProcessUtils();
    when(processUtils.runSync(
      <String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(RunResult(ProcessResult(105, 0, 'dev', ''), <String>['git', 'fetch']));
    when(processUtils.runSync(
      <String>['git', 'fetch', 'https://github.com/flutter/flutter.git', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(RunResult(ProcessResult(106, 0, '', ''), <String>['git', 'fetch']));
    when(processUtils.runSync(
      <String>['git', 'describe', '--match', '*.*.*-*.*.pre', '--first-parent', '--long', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(RunResult(ProcessResult(107, 0, 'v0.1.2-3-1234abcd', ''), <String>['git', 'describe']));
    when(processUtils.runSync(
      <String>['git', 'tag', '--contains', 'HEAD'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(
      RunResult(ProcessResult(108, 0, '', ''),
      <String>['git', 'tag', '--contains', 'HEAD'],
    ));

    GitTagVersion.determine(processUtils, workingDirectory: '.', fetchTags: true);

    verify(processUtils.runSync(
      <String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).called(1);
    verifyNever(processUtils.runSync(
      <String>['git', 'fetch', 'https://github.com/flutter/flutter.git', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    ));
    verify(processUtils.runSync(
      <String>['git', 'describe', '--match', '*.*.*-*.*.pre', '--first-parent', '--long', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).called(1);
  });

  testUsingContext('determine calls fetch --tags on master', () {
    final MockProcessUtils processUtils = MockProcessUtils();
    when(processUtils.runSync(
      <String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(RunResult(ProcessResult(108, 0, 'master', ''), <String>['git', 'fetch']));
    when(processUtils.runSync(
      <String>['git', 'fetch', 'https://github.com/flutter/flutter.git', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(RunResult(ProcessResult(109, 0, '', ''), <String>['git', 'fetch']));
    when(processUtils.runSync(
      <String>['git', 'tag', '--contains', 'HEAD'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(
      RunResult(ProcessResult(110, 0, '', ''),
      <String>['git', 'tag', '--contains', 'HEAD'],
    ));
    when(processUtils.runSync(
      <String>['git', 'describe', '--match', '*.*.*-*.*.pre', '--first-parent', '--long', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(RunResult(ProcessResult(111, 0, 'v0.1.2-3-1234abcd', ''), <String>['git', 'describe']));

    GitTagVersion.determine(processUtils, workingDirectory: '.', fetchTags: true);

    verify(processUtils.runSync(
      <String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).called(1);
    verify(processUtils.runSync(
      <String>['git', 'fetch', 'https://github.com/flutter/flutter.git', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).called(1);
    verify(processUtils.runSync(
      <String>['git', 'describe', '--match', '*.*.*-*.*.pre', '--first-parent', '--long', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).called(1);
  });
}

void _expectVersionMessage(String message) {
  expect(testLogger.statusText.trim(), message.trim());
  testLogger.clear();
}

void fakeData(
  ProcessManager pm,
  Cache cache, {
  DateTime localCommitDate,
  DateTime remoteCommitDate,
  VersionCheckStamp stamp,
  String stampJson,
  bool errorOnFetch = false,
  bool expectSetStamp = false,
  bool expectServerPing = false,
  String channel = 'master',
}) {
  ProcessResult success(String standardOutput) {
    return ProcessResult(1, 0, standardOutput, '');
  }

  ProcessResult failure(int exitCode) {
    return ProcessResult(1, exitCode, '', 'error');
  }

  when(cache.getStampFor(any)).thenAnswer((Invocation invocation) {
    expect(invocation.positionalArguments.single, VersionCheckStamp.flutterVersionCheckStampFile);

    if (stampJson != null) {
      return stampJson;
    }

    if (stamp != null) {
      return json.encode(stamp.toJson());
    }

    return null;
  });

  when(cache.setStampFor(any, any)).thenAnswer((Invocation invocation) {
    expect(invocation.positionalArguments.first, VersionCheckStamp.flutterVersionCheckStampFile);

    if (expectSetStamp) {
      stamp = VersionCheckStamp.fromJson(castStringKeyedMap(json.decode(invocation.positionalArguments[1] as String)));
      return null;
    }

    throw StateError('Unexpected call to Cache.setStampFor(${invocation.positionalArguments}, ${invocation.namedArguments})');
  });

  final Answering<ProcessResult> syncAnswer = (Invocation invocation) {
    bool argsAre(String a1, [ String a2, String a3, String a4, String a5, String a6, String a7, String a8, String a9 ]) {
      const ListEquality<String> equality = ListEquality<String>();
      final List<String> args = invocation.positionalArguments.single as List<String>;
      final List<String> expectedArgs = <String>[a1, a2, a3, a4, a5, a6, a7, a8, a9].where((String arg) => arg != null).toList();
      return equality.equals(args, expectedArgs);
    }

    bool listArgsAre(List<String> a) {
      return Function.apply(argsAre, a) as bool;
    }

    if (listArgsAre(FlutterVersion.gitLog(<String>['-n', '1', '--pretty=format:%ad', '--date=iso']))) {
      return success(localCommitDate.toString());
    } else if (argsAre('git', 'remote')) {
      return success('');
    } else if (argsAre('git', 'remote', 'add', '__flutter_version_check__', 'https://github.com/flutter/flutter.git')) {
      return success('');
    } else if (argsAre('git', 'fetch', '__flutter_version_check__', channel)) {
      if (!expectServerPing) {
        fail('Did not expect server ping');
      }
      return errorOnFetch ? failure(128) : success('');
    // Careful here!  argsAre accepts 9 arguments and FlutterVersion.gitLog adds 4.
    } else if (remoteCommitDate != null && listArgsAre(FlutterVersion.gitLog(<String>['__flutter_version_check__/$channel', '-n', '1', '--pretty=format:%ad', '--date=iso']))) {
      return success(remoteCommitDate.toString());
    } else if (argsAre('git', 'fetch', 'https://github.com/flutter/flutter.git', '--tags')) {
      return success('');
    }

    throw StateError('Unexpected call to ProcessManager.run(${invocation.positionalArguments}, ${invocation.namedArguments})');
  };

  when(pm.runSync(any, workingDirectory: anyNamed('workingDirectory'))).thenAnswer(syncAnswer);
  when(pm.run(any, workingDirectory: anyNamed('workingDirectory'))).thenAnswer((Invocation invocation) async {
    return syncAnswer(invocation);
  });

  when(pm.runSync(
    <String>['git', 'rev-parse', '--abbrev-ref', '--symbolic', '@{u}'],
    workingDirectory: anyNamed('workingDirectory'),
    environment: anyNamed('environment'),
  )).thenReturn(ProcessResult(101, 0, channel, ''));
  when(pm.runSync(
    <String>['git', 'rev-parse', '--abbrev-ref', 'HEAD'],
    workingDirectory: anyNamed('workingDirectory'),
    environment: anyNamed('environment'),
  )).thenReturn(ProcessResult(102, 0, 'branch', ''));
  when(pm.runSync(
    FlutterVersion.gitLog(<String>['-n', '1', '--pretty=format:%H']),
    workingDirectory: anyNamed('workingDirectory'),
    environment: anyNamed('environment'),
  )).thenReturn(ProcessResult(103, 0, '1234abcd', ''));
  when(pm.runSync(
    FlutterVersion.gitLog(<String>['-n', '1', '--pretty=format:%ar']),
    workingDirectory: anyNamed('workingDirectory'),
    environment: anyNamed('environment'),
  )).thenReturn(ProcessResult(104, 0, '1 second ago', ''));
  when(pm.runSync(
    <String>['git', 'fetch', 'https://github.com/flutter/flutter', '--tags'],
    workingDirectory: anyNamed('workingDirectory'),
    environment: anyNamed('environment'),
  )).thenReturn(ProcessResult(105, 0, '', ''));
  when(pm.runSync(
    <String>['git', 'tag', '--contains', 'HEAD'],
    workingDirectory: anyNamed('workingDirectory'),
    environment: anyNamed('environment'),
  )).thenReturn(ProcessResult(106, 0, '', ''));
  when(pm.runSync(
    <String>['git', 'describe', '--match', '*.*.*-*.*.pre', '--first-parent', '--long', '--tags'],
    workingDirectory: anyNamed('workingDirectory'),
    environment: anyNamed('environment'),
  )).thenReturn(ProcessResult(107, 0, 'v0.1.2-3-1234abcd', ''));
}

class MockProcessManager extends Mock implements ProcessManager {}
class MockProcessUtils extends Mock implements ProcessUtils {}
class MockCache extends Mock implements Cache {}
