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

import 'package:args/command_runner.dart';
import 'package:file/file.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/upgrade.dart';
import 'package:flutter_tools/src/version.dart';

import '../../src/context.dart';
import '../../src/fake_process_manager.dart';
import '../../src/fakes.dart' show FakeFlutterVersion;
import '../../src/test_flutter_command_runner.dart';

void main() {
  late FileSystem fileSystem;
  late BufferLogger logger;
  late FakeProcessManager processManager;
  UpgradeCommand command;
  late CommandRunner<void> runner;
  late FlutterVersion flutterVersion;

  setUpAll(() {
    Cache.disableLocking();
  });

  setUp(() {
    fileSystem = MemoryFileSystem.test();
    logger = BufferLogger.test();
    processManager = FakeProcessManager.empty();
    command = UpgradeCommand(
      verboseHelp: false,
    );
    runner = createTestCommandRunner(command);
  });

  testUsingContext('can auto-migrate a user from dev to beta', () async {
    const String startingTag = '3.0.0-1.2.pre';
    flutterVersion = FakeFlutterVersion(channel: 'dev');
    const String latestUpstreamTag = '3.0.0-1.3.pre';
    const String upstreamHeadRevision = 'deadbeef';
    final Completer<void> reEntryCompleter = Completer<void>();

    Future<void> reEnterTool() async {
      await runner.run(<String>['upgrade', '--continue', '--no-version-check']);
      reEntryCompleter.complete();
    }

    processManager.addCommands(<FakeCommand>[
      const FakeCommand(
        command: <String>['git', 'tag', '--points-at', 'HEAD'],
        stdout: startingTag,
      ),
      // Ensure we have upstream tags present locally
      const FakeCommand(
        command: <String>['git', 'fetch', '--tags'],
      ),
      const FakeCommand(
        command: <String>['git', 'rev-parse', '--verify', '@{upstream}'],
        stdout: upstreamHeadRevision,
      ),
      const FakeCommand(
        command: <String>['git', 'tag', '--points-at', upstreamHeadRevision],
        stdout: latestUpstreamTag,
      ),
      // check for uncommitted changes; empty stdout means clean checkout
      const FakeCommand(
        command: <String>['git', 'status', '-s'],
      ),

      // here the tool is upgrading the branch from dev -> beta
      const FakeCommand(
        command: <String>['git', 'fetch'],
      ),
      // test if there already exists a local beta branch; 0 exit code means yes
      const FakeCommand(
        command: <String>['git', 'show-ref', '--verify', '--quiet', 'refs/heads/beta'],
      ),
      const FakeCommand(
        command: <String>['git', 'checkout', 'beta', '--'],
      ),

      // reset instead of pull since cherrypicks from one release branch will
      // not be present on a newer one
      const FakeCommand(
        command: <String>['git', 'reset', '--hard', upstreamHeadRevision],
      ),
      // re-enter flutter command with the newer version, so that `doctor`
      // checks will be up to date
      FakeCommand(
        command: const <String>['bin/flutter', 'upgrade', '--continue', '--no-version-check'],
        onRun: reEnterTool,
        completer: reEntryCompleter,
      ),

      // commands following this are from the re-entrant `flutter upgrade --continue` call

      const FakeCommand(
        command: <String>['git', 'tag', '--points-at', 'HEAD'],
        stdout: latestUpstreamTag,
      ),
      const FakeCommand(
        command: <String>['bin/flutter', '--no-color', '--no-version-check', 'precache'],
      ),
      const FakeCommand(
        command: <String>['bin/flutter', '--no-version-check', 'doctor'],
      ),
    ]);
    await runner.run(<String>['upgrade']);
    expect(processManager, hasNoRemainingExpectations);
    expect(logger.statusText, contains("Transitioning from 'dev' to 'beta'..."));
  }, overrides: <Type, Generator>{
    FileSystem: () => fileSystem,
    FlutterVersion: () => flutterVersion,
    Logger: () => logger,
    ProcessManager: () => processManager,
  });
}
