// 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/args.dart';
import 'package:args/command_runner.dart';
import 'package:file/memory.dart';
import 'package:flutter_tools/src/artifacts.dart';
import 'package:flutter_tools/src/base/file_system.dart';
import 'package:flutter_tools/src/base/io.dart';
import 'package:flutter_tools/src/base/logger.dart';
import 'package:flutter_tools/src/base/platform.dart';
import 'package:flutter_tools/src/base/signals.dart';
import 'package:flutter_tools/src/base/terminal.dart';
import 'package:flutter_tools/src/build_info.dart';
import 'package:flutter_tools/src/build_system/build_system.dart';
import 'package:flutter_tools/src/commands/attach.dart';
import 'package:flutter_tools/src/commands/build.dart';
import 'package:flutter_tools/src/commands/build_aar.dart';
import 'package:flutter_tools/src/commands/build_apk.dart';
import 'package:flutter_tools/src/commands/build_appbundle.dart';
import 'package:flutter_tools/src/commands/build_ios.dart';
import 'package:flutter_tools/src/commands/build_ios_framework.dart';
import 'package:flutter_tools/src/commands/build_linux.dart';
import 'package:flutter_tools/src/commands/build_macos.dart';
import 'package:flutter_tools/src/commands/build_web.dart';
import 'package:flutter_tools/src/commands/build_windows.dart';
import 'package:flutter_tools/src/runner/flutter_command.dart';
import 'package:test/fake.dart';

import '../../src/common.dart';
import '../../src/context.dart';
import '../../src/fakes.dart';
import '../../src/test_build_system.dart';

class FakeTerminal extends Fake implements AnsiTerminal {
  FakeTerminal({this.stdinHasTerminal = true});

  @override
  final bool stdinHasTerminal;
}

class FakeProcessInfo extends Fake implements ProcessInfo {
  @override
  int maxRss = 0;
}

void main() {
  testUsingContext('All build commands support null safety options', () {
    final FileSystem fileSystem = MemoryFileSystem.test();
    final Platform platform = FakePlatform();
    final BufferLogger logger = BufferLogger.test();
    final List<FlutterCommand> commands = <FlutterCommand>[
      BuildWindowsCommand(logger: BufferLogger.test()),
      BuildLinuxCommand(logger: BufferLogger.test(), operatingSystemUtils: FakeOperatingSystemUtils()),
      BuildMacosCommand(logger: BufferLogger.test(), verboseHelp: false),
      BuildWebCommand(fileSystem: fileSystem, logger: BufferLogger.test(), verboseHelp: false),
      BuildApkCommand(logger: BufferLogger.test()),
      BuildIOSCommand(logger: BufferLogger.test(), verboseHelp: false),
      BuildIOSArchiveCommand(logger: BufferLogger.test(), verboseHelp: false),
      BuildAppBundleCommand(logger: BufferLogger.test()),
      BuildAarCommand(
        logger: BufferLogger.test(),
        androidSdk: FakeAndroidSdk(),
        fileSystem: fileSystem,
        verboseHelp: false,
      ),
      BuildIOSFrameworkCommand(
        logger: BufferLogger.test(),
        verboseHelp: false,
        buildSystem: FlutterBuildSystem(
          fileSystem: fileSystem,
          platform: platform,
          logger: logger,
        ),
      ),
      AttachCommand(
        artifacts: Artifacts.test(),
        stdio: FakeStdio(),
        logger: logger,
        terminal: FakeTerminal(),
        signals: Signals.test(),
        platform: platform,
        processInfo: FakeProcessInfo(),
        fileSystem: MemoryFileSystem.test(),
      ),
    ];

    for (final FlutterCommand command in commands) {
      final ArgResults results = command.argParser.parse(<String>[
        '--sound-null-safety',
        '--enable-experiment=non-nullable',
      ]);

      expect(results.wasParsed('sound-null-safety'), true);
      expect(results.wasParsed('enable-experiment'), true);
    }
  });

  testUsingContext('BuildSubCommand displays current null safety mode',
      () async {
    const BuildInfo unsound = BuildInfo(
      BuildMode.debug,
      '',
      nullSafetyMode: NullSafetyMode.unsound,
      treeShakeIcons: false,
    );

    final BufferLogger logger = BufferLogger.test();
    FakeBuildSubCommand(logger).test(unsound);
    expect(logger.statusText,
        contains('Building without sound null safety ⚠️'));
  });

  testUsingContext('Include only supported sub commands', () {
    final BuildCommand command = BuildCommand(
      androidSdk: FakeAndroidSdk(),
      buildSystem: TestBuildSystem.all(BuildResult(success: true)),
      fileSystem: MemoryFileSystem.test(),
      logger: BufferLogger.test(),
      osUtils: FakeOperatingSystemUtils(),
    );
    for (final Command<void> x in command.subcommands.values) {
      expect((x as BuildSubCommand).supported, isTrue);
    }
  });
}

class FakeBuildSubCommand extends BuildSubCommand {
  FakeBuildSubCommand(Logger logger) : super(logger: logger, verboseHelp: false);

  @override
  String get description => throw UnimplementedError();

  @override
  String get name => throw UnimplementedError();

  void test(BuildInfo buildInfo) {
    displayNullSafetyMode(buildInfo);
  }

  @override
  Future<FlutterCommandResult> runCommand() {
    throw UnimplementedError();
  }
}
