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

// @dart = 2.8

import 'package:file/memory.dart';
import 'package:flutter_tools/src/base/bot_detector.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/cache.dart';
import 'package:flutter_tools/src/globals_null_migrated.dart' as globals;
import 'package:flutter_tools/src/runner/flutter_command.dart';
import 'package:flutter_tools/src/runner/flutter_command_runner.dart';
import 'package:flutter_tools/src/version.dart';

import '../../src/context.dart';
import '../../src/fakes.dart';
import '../../src/test_flutter_command_runner.dart';
import 'utils.dart';

const String _kFlutterRoot = '/flutter/flutter';
const String _kProjectRoot = '/project';

void main() {
  group('FlutterCommandRunner', () {
    MemoryFileSystem fileSystem;
    Platform platform;

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

    setUp(() {
      fileSystem = MemoryFileSystem.test();
      fileSystem.directory(_kFlutterRoot).createSync(recursive: true);
      fileSystem.directory(_kProjectRoot).createSync(recursive: true);
      fileSystem.currentDirectory = _kProjectRoot;

      platform = FakePlatform(
        environment: <String, String>{
          'FLUTTER_ROOT': _kFlutterRoot,
        },
        version: '1 2 3 4 5',
      );
    });

    group('run', () {
      testUsingContext('checks that Flutter installation is up-to-date', () async {
        final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
        final FakeFlutterVersion version = globals.flutterVersion as FakeFlutterVersion;

        await runner.run(<String>['dummy']);

        expect(version.didCheckFlutterVersionFreshness, true);
      }, overrides: <Type, Generator>{
        FileSystem: () => fileSystem,
        ProcessManager: () => FakeProcessManager.any(),
        Platform: () => platform,
        FlutterVersion: () => FakeFlutterVersion(),
        BotDetector: () => const FakeBotDetector(false),
        OutputPreferences: () => OutputPreferences.test(),
      });

      testUsingContext('does not check that Flutter installation is up-to-date with --machine flag', () async {
        final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
        final FakeFlutterVersion version = globals.flutterVersion as FakeFlutterVersion;

        await runner.run(<String>['dummy', '--machine', '--version']);

        expect(version.didCheckFlutterVersionFreshness, false);
      }, overrides: <Type, Generator>{
        FileSystem: () => fileSystem,
        ProcessManager: () => FakeProcessManager.any(),
        Platform: () => platform,
        FlutterVersion: () => FakeFlutterVersion(),
        OutputPreferences: () => OutputPreferences.test(),
      });

      testUsingContext('does not check that Flutter installation is up-to-date with CI=true in environment', () async {
        final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
        final FakeFlutterVersion version = globals.flutterVersion as FakeFlutterVersion;

        await runner.run(<String>['dummy', '--version']);

        expect(version.didCheckFlutterVersionFreshness, false);
      }, overrides: <Type, Generator>{
        FileSystem: () => fileSystem,
        ProcessManager: () => FakeProcessManager.any(),
        Platform: () => platform,
        BotDetector: () => const FakeBotDetector(true),
      }, initializeFlutterRoot: false);

      testUsingContext('checks that Flutter installation is up-to-date with CI=true and --machine when explicit --version-check', () async {
        final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
        final FakeFlutterVersion version = globals.flutterVersion as FakeFlutterVersion;

        await runner.run(<String>['dummy', '--version', '--machine', '--version-check']);

         expect(version.didCheckFlutterVersionFreshness, true);
      }, overrides: <Type, Generator>{
        FileSystem: () => fileSystem,
        ProcessManager: () => FakeProcessManager.any(),
        Platform: () => platform,
        BotDetector: () => const FakeBotDetector(true),
      }, initializeFlutterRoot: false);

      testUsingContext('checks that Flutter installation is up-to-date if shell completion to terminal', () async {
        final FlutterCommand command = DummyFlutterCommand(name: 'bash-completion');
        final FlutterCommandRunner runner = createTestCommandRunner(command) as FlutterCommandRunner;
        final FakeFlutterVersion version = globals.flutterVersion as FakeFlutterVersion;

        await runner.run(<String>['bash-completion']);

        expect(version.didCheckFlutterVersionFreshness, true);
      }, overrides: <Type, Generator>{
        FileSystem: () => fileSystem,
        ProcessManager: () => FakeProcessManager.any(),
        Platform: () => platform,
        FlutterVersion: () => FakeFlutterVersion(),
        BotDetector: () => const FakeBotDetector(false),
        Stdio: () => FakeStdio(hasFakeTerminal: true),
      });

      testUsingContext('does not check that Flutter installation is up-to-date if redirecting shell completion', () async {
        final FlutterCommand command = DummyFlutterCommand(name: 'bash-completion');
        final FlutterCommandRunner runner = createTestCommandRunner(command) as FlutterCommandRunner;
        final FakeFlutterVersion version = globals.flutterVersion as FakeFlutterVersion;

        await runner.run(<String>['bash-completion']);

        expect(version.didCheckFlutterVersionFreshness, false);
      }, overrides: <Type, Generator>{
        FileSystem: () => fileSystem,
        ProcessManager: () => FakeProcessManager.any(),
        Platform: () => platform,
        FlutterVersion: () => FakeFlutterVersion(),
        BotDetector: () => const FakeBotDetector(false),
        Stdio: () => FakeStdio(hasFakeTerminal: false),
      });

      testUsingContext('Fetches tags when --version is used', () async {
        final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
        final FakeFlutterVersion version = globals.flutterVersion as FakeFlutterVersion;

        await runner.run(<String>['--version']);

        expect(version.didFetchTagsAndUpdate, true);
      }, overrides: <Type, Generator>{
        FileSystem: () => fileSystem,
        ProcessManager: () => FakeProcessManager.any(),
        Platform: () => platform,
        FlutterVersion: () => FakeFlutterVersion(),
        OutputPreferences: () => OutputPreferences.test(),
      });

    testUsingContext("Doesn't crash on invalid .packages file", () async {
      final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
      fileSystem.file('pubspec.yaml').createSync();
      fileSystem.file('.packages')
        ..createSync()
        ..writeAsStringSync('Not a valid package');

      await runner.run(<String>['dummy']);

    }, overrides: <Type, Generator>{
      FileSystem: () => fileSystem,
      ProcessManager: () => FakeProcessManager.any(),
      Platform: () => platform,
      OutputPreferences: () => OutputPreferences.test(),
    });

    group('getRepoPackages', () {
      String oldFlutterRoot;

      setUp(() {
        oldFlutterRoot = Cache.flutterRoot;
        Cache.flutterRoot = _kFlutterRoot;
        fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'examples'))
            .createSync(recursive: true);
        fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'packages'))
            .createSync(recursive: true);
        fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools', 'aatool'))
            .createSync(recursive: true);

        fileSystem.file(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools', 'pubspec.yaml'))
            .createSync();
        fileSystem.file(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools', 'aatool', 'pubspec.yaml'))
            .createSync();
      });

      tearDown(() {
        Cache.flutterRoot = oldFlutterRoot;
      });

      testUsingContext('', () {
        final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
        final List<String> packagePaths = runner.getRepoPackages()
          .map((Directory d) => d.path).toList();
        expect(packagePaths, <String>[
          fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools', 'aatool')).path,
          fileSystem.directory(fileSystem.path.join(_kFlutterRoot, 'dev', 'tools')).path,
        ]);
      }, overrides: <Type, Generator>{
        FileSystem: () => fileSystem,
        ProcessManager: () => FakeProcessManager.any(),
        Platform: () => platform,
        FlutterVersion: () => FakeFlutterVersion(),
        OutputPreferences: () => OutputPreferences.test(),
      });
    });

    group('wrapping', () {
      testUsingContext('checks that output wrapping is turned on when writing to a terminal', () async {
        final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
        final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
        runner.addCommand(fakeCommand);
        await runner.run(<String>['fake']);
        expect(fakeCommand.preferences.wrapText, isTrue);
      }, overrides: <Type, Generator>{
        FileSystem: () => fileSystem,
        ProcessManager: () => FakeProcessManager.any(),
        Stdio: () => FakeStdio(hasFakeTerminal: true),
        OutputPreferences: () => OutputPreferences.test(),
      }, initializeFlutterRoot: false);

      testUsingContext('checks that output wrapping is turned off when not writing to a terminal', () async {
        final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
        final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
        runner.addCommand(fakeCommand);
        await runner.run(<String>['fake']);
        expect(fakeCommand.preferences.wrapText, isFalse);
      }, overrides: <Type, Generator>{
        FileSystem: () => fileSystem,
        ProcessManager: () => FakeProcessManager.any(),
        Stdio: () => FakeStdio(hasFakeTerminal: false),
        OutputPreferences: () => OutputPreferences.test(),
      }, initializeFlutterRoot: false);

      testUsingContext('checks that output wrapping is turned off when set on the command line and writing to a terminal', () async {
        final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
        final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
        runner.addCommand(fakeCommand);
        await runner.run(<String>['--no-wrap', 'fake']);
        expect(fakeCommand.preferences.wrapText, isFalse);
      }, overrides: <Type, Generator>{
        FileSystem: () => fileSystem,
        ProcessManager: () => FakeProcessManager.any(),
        Stdio: () => FakeStdio(hasFakeTerminal: true),
        OutputPreferences: () => OutputPreferences.test(),
      }, initializeFlutterRoot: false);

      testUsingContext('checks that output wrapping is turned on when set on the command line, but not writing to a terminal', () async {
        final FlutterCommandRunner runner = createTestCommandRunner(DummyFlutterCommand()) as FlutterCommandRunner;
        final FakeFlutterCommand fakeCommand = FakeFlutterCommand();
        runner.addCommand(fakeCommand);
        await runner.run(<String>['--wrap', 'fake']);
        expect(fakeCommand.preferences.wrapText, isTrue);
      }, overrides: <Type, Generator>{
        FileSystem: () => fileSystem,
        ProcessManager: () => FakeProcessManager.any(),
        Stdio: () => FakeStdio(hasFakeTerminal: false),
        OutputPreferences: () => OutputPreferences.test(),
      }, initializeFlutterRoot: false);
    });
  });
  });
}

class FakeFlutterCommand extends FlutterCommand {
  OutputPreferences preferences;

  @override
  Future<FlutterCommandResult> runCommand() {
    preferences = globals.outputPreferences;
    return Future<FlutterCommandResult>.value(const FlutterCommandResult(ExitStatus.success));
  }

  @override
  String get description => null;

  @override
  String get name => 'fake';
}

class FakeStdio extends Stdio {
  FakeStdio({this.hasFakeTerminal});

  final bool hasFakeTerminal;

  @override
  bool get hasTerminal => hasFakeTerminal;

  @override
  int get terminalColumns => hasFakeTerminal ? 80 : null;

  @override
  int get terminalLines => hasFakeTerminal ? 24 : null;
  @override
  bool get supportsAnsiEscapes => hasFakeTerminal;
}
