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

    // legacy tag release format
    gitTagVersion = GitTagVersion.parse('v1.2.3-4-g$hash');
    expect(gitTagVersion.frameworkVersionFor(hash), '1.2.4-pre.4');
    expect(gitTagVersion.devVersion, null);
    expect(gitTagVersion.devPatch, null);

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

    // new stable tag release format
    gitTagVersion = GitTagVersion.parse('1.2.3-13-g$hash');
    expect(gitTagVersion.frameworkVersionFor(hash), '1.2.4-pre.13');
    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(GitTagVersion.parse('v1.2.3+hotfix.1-4-g$hash').frameworkVersionFor(hash), '1.2.3+hotfix.2-pre.4');
    expect(testLogger.traceText, '');
    expect(GitTagVersion.parse('1.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": 1.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 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', '*.*.*', '--first-parent', '--long', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(RunResult(ProcessResult(106, 0, 'v0.1.2-3-1234abcd', ''), <String>['git', 'describe']));

    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', '*.*.*', '--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', '*.*.*', '--first-parent', '--long', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(RunResult(ProcessResult(107, 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);
    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', '*.*.*', '--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', 'describe', '--match', '*.*.*', '--first-parent', '--long', '--tags'],
      workingDirectory: anyNamed('workingDirectory'),
      environment: anyNamed('environment'),
    )).thenReturn(RunResult(ProcessResult(110, 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', '*.*.*', '--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', 'describe', '--match', '*.*.*', '--first-parent', '--long', '--tags'],
    workingDirectory: anyNamed('workingDirectory'),
    environment: anyNamed('environment'),
  )).thenReturn(ProcessResult(106, 0, 'v0.1.2-3-1234abcd', ''));
}

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