// 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:file/memory.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/commands/channel.dart';
import 'package:flutter_tools/src/globals.dart' as globals;
import 'package:flutter_tools/src/version.dart';

import '../src/common.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() {
  group('channel', () {
    late FakeProcessManager fakeProcessManager;

    setUp(() {
      fakeProcessManager = FakeProcessManager.empty();
    });

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

    Future<void> simpleChannelTest(List<String> args) async {
      fakeProcessManager.addCommands(const <FakeCommand>[
        FakeCommand(
          command: <String>['git', 'branch', '-r'],
          stdout:
            '  origin/branch-1\n'
            '  origin/branch-2\n'
            '  origin/master\n'
            '  origin/main\n'
            '  origin/stable\n'
            '  origin/beta',
        ),
      ]);
      final ChannelCommand command = ChannelCommand();
      final CommandRunner<void> runner = createTestCommandRunner(command);
      await runner.run(args);
      expect(testLogger.errorText, hasLength(0));
      // The bots may return an empty list of channels (network hiccup?)
      // and when run locally the list of branches might be different
      // so we check for the header text rather than any specific channel name.
      expect(
        testLogger.statusText,
        containsIgnoringWhitespace('Flutter channels:'),
      );
    }

    testUsingContext('list', () async {
      await simpleChannelTest(<String>['channel']);
    }, overrides: <Type, Generator>{
      ProcessManager: () => fakeProcessManager,
      FileSystem: () => MemoryFileSystem.test(),
    });

    testUsingContext('verbose list', () async {
      await simpleChannelTest(<String>['channel', '-v']);
    }, overrides: <Type, Generator>{
      ProcessManager: () => fakeProcessManager,
      FileSystem: () => MemoryFileSystem.test(),
    });

    testUsingContext('sorted by stability', () async {
      final ChannelCommand command = ChannelCommand();
      final CommandRunner<void> runner = createTestCommandRunner(command);

      fakeProcessManager.addCommand(
        const FakeCommand(
          command: <String>['git', 'branch', '-r'],
          stdout: 'origin/beta\n'
              'origin/master\n'
              'origin/main\n'
              'origin/stable\n',
        ),
      );

      await runner.run(<String>['channel']);
      expect(fakeProcessManager, hasNoRemainingExpectations);
      expect(testLogger.errorText, hasLength(0));
      expect(testLogger.statusText,
        'Flutter channels:\n'
        '* master (latest development branch, for contributors)\n'
        '  main (latest development branch, follows master channel)\n'
        '  beta (updated monthly, recommended for experienced users)\n'
        '  stable (updated quarterly, for new users and for production app releases)\n',
      );

      // clear buffer for next process
      testLogger.clear();

      // Extra branches.
      fakeProcessManager.addCommand(
        const FakeCommand(
          command: <String>['git', 'branch', '-r'],
          stdout: 'origin/beta\n'
              'origin/master\n'
              'origin/dependabot/bundler\n'
              'origin/main\n'
              'origin/v1.4.5-hotfixes\n'
              'origin/stable\n',
        ),
      );

      await runner.run(<String>['channel']);
      expect(fakeProcessManager, hasNoRemainingExpectations);
      expect(testLogger.errorText, hasLength(0));
      expect(testLogger.statusText,
        'Flutter channels:\n'
        '* master (latest development branch, for contributors)\n'
        '  main (latest development branch, follows master channel)\n'
        '  beta (updated monthly, recommended for experienced users)\n'
        '  stable (updated quarterly, for new users and for production app releases)\n',
      );

      // clear buffer for next process
      testLogger.clear();

      // Missing branches.
      fakeProcessManager.addCommand(
        const FakeCommand(
          command: <String>['git', 'branch', '-r'],
          stdout: 'origin/master\n'
              'origin/dependabot/bundler\n'
              'origin/v1.4.5-hotfixes\n'
              'origin/stable\n'
              'origin/beta\n',
        ),
      );

      await runner.run(<String>['channel']);
      expect(fakeProcessManager, hasNoRemainingExpectations);
      expect(testLogger.errorText, hasLength(0));
      // check if available official channels are in order of stability
      int prev = -1;
      int next = -1;
      for (final String branch in kOfficialChannels) {
        next = testLogger.statusText.indexOf(branch);
        if (next != -1) {
          expect(prev < next, isTrue);
          prev = next;
        }
      }

    }, overrides: <Type, Generator>{
      ProcessManager: () => fakeProcessManager,
      FileSystem: () => MemoryFileSystem.test(),
    });

    testUsingContext('ignores lines with unexpected output', () async {
      fakeProcessManager.addCommand(
        const FakeCommand(
          command: <String>['git', 'branch', '-r'],
          stdout: 'origin/beta\n'
              'origin/stable\n'
              'upstream/beta\n'
              'upstream/stable\n'
              'foo',
        ),
      );

      final ChannelCommand command = ChannelCommand();
      final CommandRunner<void> runner = createTestCommandRunner(command);
      await runner.run(<String>['channel']);

      expect(fakeProcessManager, hasNoRemainingExpectations);
      expect(testLogger.errorText, hasLength(0));
      expect(testLogger.statusText,
        'Flutter channels:\n'
        '* beta (updated monthly, recommended for experienced users)\n'
        '  stable (updated quarterly, for new users and for production app releases)\n'
      );
    }, overrides: <Type, Generator>{
      ProcessManager: () => fakeProcessManager,
      FileSystem: () => MemoryFileSystem.test(),
      FlutterVersion: () => FakeFlutterVersion(branch: 'beta'),
    });

    testUsingContext('handles custom branches', () async {
      fakeProcessManager.addCommand(
        const FakeCommand(
          command: <String>['git', 'branch', '-r'],
          stdout: 'origin/beta\n'
              'origin/stable\n'
              'origin/foo',
        ),
      );

      final ChannelCommand command = ChannelCommand();
      final CommandRunner<void> runner = createTestCommandRunner(command);
      await runner.run(<String>['channel']);

      expect(fakeProcessManager, hasNoRemainingExpectations);
      expect(testLogger.errorText, hasLength(0));
      expect(testLogger.statusText,
        'Flutter channels:\n'
        '  beta (updated monthly, recommended for experienced users)\n'
        '  stable (updated quarterly, for new users and for production app releases)\n'
        '* foo\n'
        '\n'
        'Currently not on an official channel.\n',
      );
    }, overrides: <Type, Generator>{
      ProcessManager: () => fakeProcessManager,
      FileSystem: () => MemoryFileSystem.test(),
      FlutterVersion: () => FakeFlutterVersion(branch: 'foo'),
    });

    testUsingContext('removes duplicates', () async {
      fakeProcessManager.addCommand(
        const FakeCommand(
          command: <String>['git', 'branch', '-r'],
          stdout: 'origin/beta\n'
              'origin/stable\n'
              'upstream/beta\n'
              'upstream/stable\n',
        ),
      );

      final ChannelCommand command = ChannelCommand();
      final CommandRunner<void> runner = createTestCommandRunner(command);
      await runner.run(<String>['channel']);

      expect(fakeProcessManager, hasNoRemainingExpectations);
      expect(testLogger.errorText, hasLength(0));
      expect(testLogger.statusText,
        'Flutter channels:\n'
        '* beta (updated monthly, recommended for experienced users)\n'
        '  stable (updated quarterly, for new users and for production app releases)\n'
      );
    }, overrides: <Type, Generator>{
      ProcessManager: () => fakeProcessManager,
      FileSystem: () => MemoryFileSystem.test(),
      FlutterVersion: () => FakeFlutterVersion(branch: 'beta'),
    });

    testUsingContext('can switch channels', () async {
      fakeProcessManager.addCommands(const <FakeCommand>[
        FakeCommand(
          command: <String>['git', 'fetch'],
        ),
        FakeCommand(
          command: <String>['git', 'show-ref', '--verify', '--quiet', 'refs/heads/beta'],
        ),
        FakeCommand(
          command: <String>['git', 'checkout', 'beta', '--']
        ),
        FakeCommand(
          command: <String>['bin/flutter', '--no-color', '--no-version-check', 'precache'],
        ),
      ]);

      final ChannelCommand command = ChannelCommand();
      final CommandRunner<void> runner = createTestCommandRunner(command);
      await runner.run(<String>['channel', 'beta']);

      expect(fakeProcessManager, hasNoRemainingExpectations);
      expect(
        testLogger.statusText,
        containsIgnoringWhitespace("Switching to flutter channel 'beta'..."),
      );
      expect(testLogger.errorText, hasLength(0));

      fakeProcessManager.addCommands(const <FakeCommand>[
        FakeCommand(
          command: <String>['git', 'fetch'],
        ),
        FakeCommand(
          command: <String>['git', 'show-ref', '--verify', '--quiet', 'refs/heads/stable'],
        ),
        FakeCommand(
          command: <String>['git', 'checkout', 'stable', '--'],
        ),
        FakeCommand(
          command: <String>['bin/flutter', '--no-color', '--no-version-check', 'precache'],
        ),
      ]);

      await runner.run(<String>['channel', 'stable']);

      expect(fakeProcessManager, hasNoRemainingExpectations);
    }, overrides: <Type, Generator>{
      FileSystem: () => MemoryFileSystem.test(),
      ProcessManager: () => fakeProcessManager,
    });

    testUsingContext('switching channels prompts to run flutter upgrade', () async {
      fakeProcessManager.addCommands(const <FakeCommand>[
        FakeCommand(
          command: <String>['git', 'fetch'],
        ),
        FakeCommand(
          command: <String>['git', 'show-ref', '--verify', '--quiet', 'refs/heads/beta'],
        ),
        FakeCommand(
            command: <String>['git', 'checkout', 'beta', '--']
        ),
        FakeCommand(
          command: <String>['bin/flutter', '--no-color', '--no-version-check', 'precache'],
        ),
      ]);

      final ChannelCommand command = ChannelCommand();
      final CommandRunner<void> runner = createTestCommandRunner(command);
      await runner.run(<String>['channel', 'beta']);

      expect(
        testLogger.statusText,
        containsIgnoringWhitespace("Successfully switched to flutter channel 'beta'."),
      );
      expect(
        testLogger.statusText,
        containsIgnoringWhitespace(
          "To ensure that you're on the latest build "
          "from this channel, run 'flutter upgrade'"),
      );
      expect(testLogger.errorText, hasLength(0));
      expect(fakeProcessManager, hasNoRemainingExpectations);
    }, overrides: <Type, Generator>{
      FileSystem: () => MemoryFileSystem.test(),
      ProcessManager: () => fakeProcessManager,
    });

    // This verifies that bug https://github.com/flutter/flutter/issues/21134
    // doesn't return.
    testUsingContext('removes version stamp file when switching channels', () async {
      fakeProcessManager.addCommands(const <FakeCommand>[
        FakeCommand(
          command: <String>['git', 'fetch'],
        ),
        FakeCommand(
          command: <String>['git', 'show-ref', '--verify', '--quiet', 'refs/heads/beta'],
        ),
        FakeCommand(
          command: <String>['git', 'checkout', 'beta', '--']
        ),
        FakeCommand(
          command: <String>['bin/flutter', '--no-color', '--no-version-check', 'precache'],
        ),
      ]);

      final File versionCheckFile = globals.cache.getStampFileFor(
        VersionCheckStamp.flutterVersionCheckStampFile,
      );

      /// Create a bogus "leftover" version check file to make sure it gets
      /// removed when the channel changes. The content doesn't matter.
      versionCheckFile.createSync(recursive: true);
      versionCheckFile.writeAsStringSync('''
        {
          "lastTimeVersionWasChecked": "2151-08-29 10:17:30.763802",
          "lastKnownRemoteVersion": "2151-09-26 15:56:19.000Z"
        }
      ''');

      final ChannelCommand command = ChannelCommand();
      final CommandRunner<void> runner = createTestCommandRunner(command);
      await runner.run(<String>['channel', 'beta']);

      expect(testLogger.statusText, isNot(contains('A new version of Flutter')));
      expect(testLogger.errorText, hasLength(0));
      expect(versionCheckFile.existsSync(), isFalse);
      expect(fakeProcessManager, hasNoRemainingExpectations);
    }, overrides: <Type, Generator>{
      FileSystem: () => MemoryFileSystem.test(),
      ProcessManager: () => fakeProcessManager,
    });
  });
}
