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

import './common.dart';
import '../../../packages/flutter_tools/test/src/fake_process_manager.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'),
  });
}
