// 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 'package:args/command_runner.dart';
import 'package:conductor_core/src/candidates.dart';
import 'package:conductor_core/src/repository.dart';
import 'package:file/memory.dart';
import 'package:platform/platform.dart';

import './common.dart';

void main() {
  group('candidates command', () {
    const String flutterRoot = '/flutter';
    const String flutterBinPath = '$flutterRoot/bin/flutter';
    const String checkoutsParentDirectory = '$flutterRoot/dev/tools/';
    const String remoteName = 'origin';

    late MemoryFileSystem fileSystem;
    late FakePlatform platform;
    late TestStdio stdio;
    late FakeProcessManager processManager;
    final String operatingSystem = const LocalPlatform().operatingSystem;

    setUp(() {
      stdio = TestStdio();
      fileSystem = MemoryFileSystem.test();
    });

    CommandRunner<void> createRunner({
      required Checkouts checkouts,
    }) {
      final CandidatesCommand command = CandidatesCommand(
        checkouts: checkouts,
        flutterRoot: fileSystem.directory(flutterRoot),
      );
      return CommandRunner<void>('clean-test', '')..addCommand(command);
    }

    test('prints only branches from targeted remote', () async {
      const String currentVersion = '1.2.3';
      const String branch = 'flutter-1.3-candidate.0';

      processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['git', 'fetch', remoteName],
        ),
        const FakeCommand(
          command: <String>[flutterBinPath, 'help'],
        ),
        const FakeCommand(
          command: <String>[flutterBinPath, '--version', '--machine'],
          stdout: '{"frameworkVersion": "$currentVersion"}',
        ),
        FakeCommand(
          command: const <String>[
            'git',
            'branch',
            '--no-color',
            '--remotes',
            '--list',
            '$remoteName/*',
          ],
          stdout: <String>[
            'other-remote/flutter-5.0-candidate.0',
            '$remoteName/$branch',
          ].join('\n'),
        ),
      ]);
      final String pathSeparator = operatingSystem == 'windows' ? r'\' : '/';

      platform = FakePlatform(
        environment: <String, String>{
          'HOME': <String>['path', 'to', 'home'].join(pathSeparator),
        },
        pathSeparator: pathSeparator,
      );
      final Checkouts checkouts = Checkouts(
        fileSystem: fileSystem,
        parentDirectory: fileSystem.directory(checkoutsParentDirectory),
        platform: platform,
        processManager: processManager,
        stdio: stdio,
      );

      final CommandRunner<void> runner = createRunner(checkouts: checkouts);
      await runner.run(<String>['candidates', '--$kRemote', remoteName]);
      expect(stdio.stdout.contains('currentVersion = $currentVersion'), true);
      expect(stdio.stdout.contains(branch), true);
      expect(stdio.stdout.contains('flutter-5.0-candidate.0'), false);
    });

    test('does not print branches older or equal to current version', () async {
      const String currentVersion = '2.3.0-13.0.pre.48';
      const String newBranch = 'flutter-2.4-candidate.0';
      const String oldBranch = 'flutter-1.0-candidate.0';
      const String currentBranch = 'flutter-2.3-candidate.13';

      processManager = FakeProcessManager.list(<FakeCommand>[
        const FakeCommand(
          command: <String>['git', 'fetch', remoteName],
        ),
        const FakeCommand(
          command: <String>[flutterBinPath, 'help'],
        ),
        const FakeCommand(
          command: <String>[flutterBinPath, '--version', '--machine'],
          stdout: '{"frameworkVersion": "$currentVersion"}',
        ),
        FakeCommand(
          command: const <String>[
            'git',
            'branch',
            '--no-color',
            '--remotes',
            '--list',
            '$remoteName/*',
          ],
          stdout: <String>[
            '$remoteName/$oldBranch',
            '$remoteName/$currentBranch',
            '$remoteName/$newBranch',
          ].join('\n'),
        ),
      ]);
      final String pathSeparator = operatingSystem == 'windows' ? r'\' : '/';

      platform = FakePlatform(
        environment: <String, String>{
          'HOME': <String>['path', 'to', 'home'].join(pathSeparator),
        },
        pathSeparator: pathSeparator,
      );
      final Checkouts checkouts = Checkouts(
        fileSystem: fileSystem,
        parentDirectory: fileSystem.directory(checkoutsParentDirectory),
        platform: platform,
        processManager: processManager,
        stdio: stdio,
      );

      final CommandRunner<void> runner = createRunner(checkouts: checkouts);
      await runner.run(<String>['candidates', '--$kRemote', remoteName]);
      expect(stdio.stdout.contains('currentVersion = $currentVersion'), true);
      expect(stdio.stdout.contains(newBranch), true);
      expect(stdio.stdout.contains(oldBranch), false);
      expect(stdio.stdout.contains(currentBranch), false);
    });
  }, onPlatform: <String, dynamic>{
    'windows': const Skip('Flutter Conductor only supported on macos/linux'),
  });
}
