// 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:flutter_tools_extension_linux_prototype/flutter_tools_extension_linux_prototype.dart';
import 'package:meta/meta.dart';

import 'runner.dart' as runner;
import 'src/base/context.dart';
import 'src/base/io.dart';
import 'src/base/logger.dart';
import 'src/base/platform.dart';
import 'src/base/template.dart';
import 'src/base/terminal.dart';
import 'src/base/user_messages.dart';
import 'src/build_system/build_targets.dart';
import 'src/build_system/targets/hook_runner_native.dart' show FlutterHookRunnerNative;
import 'src/cache.dart';
import 'src/commands/analyze.dart';
import 'src/commands/assemble.dart';
import 'src/commands/attach.dart';
import 'src/commands/build.dart';
import 'src/commands/channel.dart';
import 'src/commands/clean.dart';
import 'src/commands/config.dart';
import 'src/commands/create.dart';
import 'src/commands/custom_devices.dart';
import 'src/commands/daemon.dart';
import 'src/commands/debug_adapter.dart';
import 'src/commands/devices.dart';
import 'src/commands/doctor.dart';
import 'src/commands/downgrade.dart';
import 'src/commands/drive.dart';
import 'src/commands/emulators.dart';
import 'src/commands/generate.dart';
import 'src/commands/generate_localizations.dart';
import 'src/commands/ide_config.dart';
import 'src/commands/install.dart';
import 'src/commands/logs.dart';
import 'src/commands/packages.dart';
import 'src/commands/precache.dart';
import 'src/commands/run.dart';
import 'src/commands/screenshot.dart';
import 'src/commands/shell_completion.dart';
import 'src/commands/symbolize.dart';
import 'src/commands/test.dart';
import 'src/commands/update_packages.dart';
import 'src/commands/upgrade.dart';
import 'src/commands/widget_preview.dart';
import 'src/context/tool_context.dart';
import 'src/context/tool_dependencies.dart';
import 'src/devtools_launcher.dart';
import 'src/experimental/extension_discovery.dart';
import 'src/experimental/extension_manager.dart';
import 'src/features.dart';
import 'src/globals.dart' as globals;
// Files in `isolated` are intentionally excluded from google3 tooling.
import 'src/hook_runner.dart' show FlutterHookRunner;
import 'src/isolated/build_targets.dart';
import 'src/isolated/mustache_template.dart';
import 'src/isolated/native_assets/test/native_assets.dart';
import 'src/isolated/resident_web_runner.dart';
import 'src/native_assets.dart';
import 'src/pre_run_validator.dart';
import 'src/project_validator.dart';
import 'src/resident_runner.dart';
import 'src/runner/flutter_command.dart';
import 'src/runner/flutter_command_runner.dart';
import 'src/web/web_runner.dart';

/// Main entry point for commands.
///
/// This function is intended to be used from the `flutter` command line tool.
Future<void> main(List<String> args) async {
  final bool veryVerbose = args.contains('-vv');
  final bool verbose = args.contains('-v') || args.contains('--verbose') || veryVerbose;
  final bool prefixedErrors = args.contains('--prefixed-errors');
  // Support universal help idioms.
  final int powershellHelpIndex = args.indexOf('-?');
  if (powershellHelpIndex != -1) {
    args[powershellHelpIndex] = '-h';
  }
  final int slashQuestionHelpIndex = args.indexOf('/?');
  if (slashQuestionHelpIndex != -1) {
    args[slashQuestionHelpIndex] = '-h';
  }

  final String? commandName = findCommandName(args);
  final doctor = commandName == 'doctor';
  final bool help =
      args.contains('-h') ||
      args.contains('--help') ||
      commandName == 'help' ||
      (args.length == 1 && verbose);
  final bool muteCommandLogging = (help || doctor) && !veryVerbose;
  final bool verboseHelp = help && verbose;
  final daemon = commandName == 'daemon';
  final widgetPreviews = commandName == WidgetPreviewCommand.kWidgetPreview;
  final bool runMachine = args.contains('--machine');

  // Cache.flutterRoot must be set early because other features use it (e.g.
  // enginePath's initializer uses it). This can only work with the real
  // instances of the platform or filesystem, so just use those.
  Cache.flutterRoot = Cache.defaultFlutterRoot(
    platform: const LocalPlatform(),
    fileSystem: globals.localFileSystem,
    userMessages: UserMessages(),
  );

  await runner.run(
    args,
    (ToolDependencies toolDependencies) {
      final manager = ExtensionManager(
        hostPlatform: globals.os.hostPlatform,
        logger: globals.logger,
        entryPoints: <ExtensionEntryPoint>[linuxExtensionEntryPoint],
        featureFlags: featureFlags,
      );
      return generateCommands(
        toolDependencies: toolDependencies,
        verboseHelp: verboseHelp,
        verbose: verbose,
        extensionManager: manager,
      );
    },
    verbose: verbose,
    muteCommandLogging: muteCommandLogging,
    verboseHelp: verboseHelp,
    overrides: <Type, Generator>{
      FlutterHookRunner: () => FlutterHookRunnerNative(),
      // The web runner is not supported in google3 because it depends
      // on dwds.
      WebRunnerFactory: () => DwdsWebRunnerFactory(),
      // The mustache dependency is different in google3
      TemplateRenderer: () => const MustacheTemplateRenderer(),
      // The devtools launcher is not supported in google3 because it depends on
      // devtools source code.
      DevtoolsLauncher: () => DevtoolsServerLauncher(
        processManager: globals.processManager,
        artifacts: globals.artifacts!,
        logger: globals.logger,
        botDetector: globals.botDetector,
      ),
      BuildTargets: () => const BuildTargetsImpl(),
      Logger: () {
        final loggerFactory = LoggerFactory(
          outputPreferences: globals.outputPreferences,
          terminal: globals.terminal,
          stdio: globals.stdio,
        );
        return loggerFactory.createLogger(
          daemon: daemon,
          machine: runMachine,
          verbose: verbose && !muteCommandLogging,
          prefixedErrors: prefixedErrors,
          windows: globals.platform.isWindows,
          widgetPreviews: widgetPreviews,
        );
      },
      AnsiTerminal: () {
        return AnsiTerminal(
          stdio: globals.stdio,
          platform: globals.platform,
          now: DateTime.now(),
          // So that we don't animate anything before calling applyFeatureFlags, default
          // the animations to disabled in real apps.
          defaultCliAnimationEnabled: false,
          shutdownHooks: globals.shutdownHooks,
        );
        // runner.run calls "terminal.applyFeatureFlags()"
      },
      PreRunValidator: () => PreRunValidator(fileSystem: globals.fs),
      TestCompilerNativeAssetsBuilder: () => const TestCompilerNativeAssetsBuilderImpl(),
    },
    shutdownHooks: globals.shutdownHooks,
  );
}

/// The name of the command in [args], or null if there isn't one.
///
/// Global options can come before the command, so it can't be found by
/// position. A throwaway parser walks past them instead: trailing options are
/// disabled, so parsing stops at the command and leaves it at the head of
/// [ArgResults.rest]. `help` is the exception, since the command runner
/// registers it on the parser itself and so reports it as a parsed command.
@visibleForTesting
String? findCommandName(List<String> args, {ToolContext? toolContext}) {
  final ArgResults results;
  try {
    results = FlutterCommandRunner(
      toolContext: toolContext ?? _FallbackToolContext(),
    ).argParser.parse(args);
  } on ArgParserException {
    // The real parser will complain about these later.
    return null;
  }
  return results.command?.name ?? results.rest.firstOrNull;
}

class _FallbackToolContext implements ToolContext {
  _FallbackToolContext({OutputPreferences? outputPreferences})
    : _outputPreferences = outputPreferences;

  final OutputPreferences? _outputPreferences;

  @override
  OutputPreferences get outputPreferences {
    if (_outputPreferences != null) {
      return _outputPreferences;
    }
    try {
      return globals.outputPreferences;
    } on Object catch (_) {
      return OutputPreferences.test();
    }
  }

  @override
  dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}

List<FlutterCommand> generateCommands({
  required ToolDependencies toolDependencies,
  required bool verbose,
  required bool verboseHelp,
  ExtensionManager? extensionManager,
}) => <FlutterCommand>[
  AnalyzeCommand(
    verboseHelp: verboseHelp,
    fileSystem: toolDependencies.toolContext.fs,
    platform: toolDependencies.toolContext.platform,
    processManager: toolDependencies.toolContext.processManager,
    logger: toolDependencies.toolContext.logger,
    terminal: toolDependencies.toolContext.terminal,
    artifacts: toolDependencies.toolContext.artifacts,
    // new ProjectValidators should be added here for the --suggestions to run
    allProjectValidators: <ProjectValidator>[
      GeneralInfoProjectValidator(),
      VariableDumpMachineProjectValidator(
        logger: toolDependencies.toolContext.logger,
        fileSystem: toolDependencies.toolContext.fs,
        platform: toolDependencies.toolContext.platform,
        git: toolDependencies.toolContext.git,
      ),
    ],
    suppressAnalytics: !toolDependencies.analytics.okToSend,
  ),
  AssembleCommand(verboseHelp: verboseHelp, buildSystem: toolDependencies.buildSystem),
  AttachCommand(
    verboseHelp: verboseHelp,
    stdio: toolDependencies.toolContext.stdio,
    logger: toolDependencies.toolContext.logger,
    terminal: toolDependencies.toolContext.terminal,
    signals: toolDependencies.toolContext.signals,
    platform: toolDependencies.toolContext.platform,
    processInfo: ProcessInfo(toolDependencies.toolContext.fs),
    fileSystem: toolDependencies.toolContext.fs,
  ),
  BuildCommand(
    fileSystem: toolDependencies.toolContext.fs,
    buildSystem: toolDependencies.buildSystem,
    osUtils: toolDependencies.toolContext.os,
    verboseHelp: verboseHelp,
    androidSdk: toolDependencies.androidContext.androidSdk,
    logger: toolDependencies.toolContext.logger,
    config: toolDependencies.toolContext.config,
    platform: toolDependencies.toolContext.platform,
    fileSystemUtils: toolDependencies.toolContext.fileSystemUtils,
    terminal: toolDependencies.toolContext.terminal,
    plistParser: toolDependencies.appleContext.plistParser,
    processUtils: toolDependencies.toolContext.processUtils,
    processManager: toolDependencies.toolContext.processManager,
    templateRenderer: const MustacheTemplateRenderer(),
    xcode: toolDependencies.appleContext.xcode,
    artifacts: toolDependencies.toolContext.artifacts,
    cache: toolDependencies.toolContext.cache,
    flutterVersion: toolDependencies.toolContext.flutterVersion,
  ),
  ChannelCommand(verboseHelp: verboseHelp),
  CleanCommand(
    verbose: verbose,
    toolContext: toolDependencies.toolContext,
    xcode: toolDependencies.appleContext.xcode,
    xcodeProjectInterpreter: toolDependencies.appleContext.xcodeProjectInterpreter,
  ),
  ConfigCommand(verboseHelp: verboseHelp, extensionManager: extensionManager),
  CustomDevicesCommand(
    customDevicesConfig: toolDependencies.toolContext.customDevicesConfig,
    operatingSystemUtils: toolDependencies.toolContext.os,
    terminal: toolDependencies.toolContext.terminal,
    platform: toolDependencies.toolContext.platform,
    featureFlags: featureFlags,
    processManager: toolDependencies.toolContext.processManager,
    fileSystem: toolDependencies.toolContext.fs,
    logger: toolDependencies.toolContext.logger,
  ),
  CreateCommand(verboseHelp: verboseHelp),
  DaemonCommand(hidden: !verboseHelp),
  DebugAdapterCommand(verboseHelp: verboseHelp),
  DevicesCommand(verboseHelp: verboseHelp),
  DoctorCommand(verbose: verbose, extensionManager: extensionManager),
  DowngradeCommand(verboseHelp: verboseHelp, logger: toolDependencies.toolContext.logger),
  DriveCommand(
    verboseHelp: verboseHelp,
    fileSystem: toolDependencies.toolContext.fs,
    logger: toolDependencies.toolContext.logger,
    platform: toolDependencies.toolContext.platform,
    terminal: toolDependencies.toolContext.terminal,
    outputPreferences: toolDependencies.toolContext.outputPreferences,
    signals: toolDependencies.toolContext.signals,
  ),
  EmulatorsCommand(),
  GenerateCommand(),
  GenerateLocalizationsCommand(
    fileSystem: toolDependencies.toolContext.fs,
    logger: toolDependencies.toolContext.logger,
    artifacts: toolDependencies.toolContext.artifacts,
    processManager: toolDependencies.toolContext.processManager,
  ),
  InstallCommand(verboseHelp: verboseHelp),
  LogsCommand(sigint: ProcessSignal.sigint, sigterm: ProcessSignal.sigterm),
  PackagesCommand(),
  PrecacheCommand(
    verboseHelp: verboseHelp,
    cache: toolDependencies.toolContext.cache,
    logger: toolDependencies.toolContext.logger,
    platform: toolDependencies.toolContext.platform,
    featureFlags: featureFlags,
  ),
  RunCommand(verboseHelp: verboseHelp),
  ScreenshotCommand(fs: toolDependencies.toolContext.fs),
  ShellCompletionCommand(),
  TestCommand(
    verboseHelp: verboseHelp,
    verbose: verbose,
    nativeAssetsBuilder: toolDependencies.toolContext.nativeAssetsBuilder,
  ),
  WidgetPreviewCommand(
    verboseHelp: verboseHelp,
    logger: toolDependencies.toolContext.logger,
    fs: toolDependencies.toolContext.fs,
    projectFactory: toolDependencies.toolContext.projectFactory,
    cache: toolDependencies.toolContext.cache,
    platform: toolDependencies.toolContext.platform,
    shutdownHooks: toolDependencies.toolContext.shutdownHooks,
    os: toolDependencies.toolContext.os,
    processManager: toolDependencies.toolContext.processManager,
    artifacts: toolDependencies.toolContext.artifacts,
    terminal: toolDependencies.toolContext.terminal,
  ),
  UpgradeCommand(verboseHelp: verboseHelp),
  SymbolizeCommand(
    stdio: toolDependencies.toolContext.stdio,
    fileSystem: toolDependencies.toolContext.fs,
  ),
  // Development-only commands. These are always hidden,
  IdeConfigCommand(),
  UpdatePackagesCommand(verboseHelp: verboseHelp),
];

/// An abstraction for instantiation of the correct logger type.
///
/// Our logger class hierarchy and runtime requirements are overly complicated.
class LoggerFactory {
  LoggerFactory({
    required Terminal terminal,
    required Stdio stdio,
    required OutputPreferences outputPreferences,
    StopwatchFactory stopwatchFactory = const StopwatchFactory(),
  }) : _terminal = terminal,
       _stdio = stdio,
       _stopwatchFactory = stopwatchFactory,
       _outputPreferences = outputPreferences;

  final Terminal _terminal;
  final Stdio _stdio;
  final StopwatchFactory _stopwatchFactory;
  final OutputPreferences _outputPreferences;

  /// Create the appropriate logger for the current platform and configuration.
  Logger createLogger({
    required bool verbose,
    required bool prefixedErrors,
    required bool machine,
    required bool daemon,
    required bool windows,
    required bool widgetPreviews,
  }) {
    Logger logger;
    if (windows) {
      logger = WindowsStdoutLogger(
        terminal: _terminal,
        stdio: _stdio,
        outputPreferences: _outputPreferences,
        stopwatchFactory: _stopwatchFactory,
      );
    } else {
      logger = StdoutLogger(
        terminal: _terminal,
        stdio: _stdio,
        outputPreferences: _outputPreferences,
        stopwatchFactory: _stopwatchFactory,
      );
    }
    if (verbose) {
      logger = VerboseLogger(logger, stopwatchFactory: _stopwatchFactory);
    }
    if (prefixedErrors) {
      logger = PrefixedErrorLogger(logger);
    }
    if (widgetPreviews) {
      return WidgetPreviewMachineAwareLogger(logger, machine: machine, verbose: verbose);
    }
    if (daemon) {
      return NotifyingLogger(verbose: verbose, parent: logger);
    }
    if (machine) {
      return MachineOutputLogger(parent: logger);
    }
    return logger;
  }
}
