// 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/android/android_workflow.dart' as android_workflow;
import 'src/android/gradle.dart';
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/experimental/templates.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,
      );
      final templateManager = ExtensionTemplateManager(
        extensionManager: manager,
        fileSystem: toolDependencies.toolContext.fs,
        logger: toolDependencies.toolContext.logger,
        featureFlags: featureFlags,
      );
      return generateCommands(
        toolDependencies: toolDependencies,
        verboseHelp: verboseHelp,
        verbose: verbose,
        extensionManager: manager,
        extensionTemplateManager: templateManager,
      );
    },
    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 = null;

  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,
  ExtensionTemplateManager? extensionTemplateManager,
}) => <FlutterCommand>[
  AnalyzeCommand(
    allProjectValidators: <ProjectValidator>[
      GeneralInfoProjectValidator(),
      VariableDumpMachineProjectValidator(
        logger: toolDependencies.toolContext.logger,
        fileSystem: toolDependencies.toolContext.fs,
        platform: toolDependencies.toolContext.platform,
        git: toolDependencies.toolContext.git,
      ),
    ],
    suppressAnalytics: !toolDependencies.analytics.okToSend,
    toolContext: toolDependencies.toolContext,
    verboseHelp: verboseHelp,
  ),
  AssembleCommand(
    buildSystem: toolDependencies.buildSystem,
    featureFlags: toolDependencies.featureFlags,
    toolContext: toolDependencies.toolContext,
    verboseHelp: verboseHelp,
  ),
  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(
    androidBuilder: AndroidGradleBuilder.fromContexts(
      analytics: toolDependencies.analytics,
      androidContext: toolDependencies.androidContext,
      toolContext: toolDependencies.toolContext,
    ),
    androidContext: toolDependencies.androidContext,
    appleContext: toolDependencies.appleContext,
    buildSystem: toolDependencies.buildSystem,
    featureFlags: toolDependencies.featureFlags,
    templateRenderer: const MustacheTemplateRenderer(),
    toolContext: toolDependencies.toolContext,
    verboseHelp: verboseHelp,
  ),
  ChannelCommand(verboseHelp: verboseHelp, toolContext: toolDependencies.toolContext),
  CleanCommand(
    verbose: verbose,
    toolContext: toolDependencies.toolContext,
    xcode: toolDependencies.appleContext.xcode,
    xcodeProjectInterpreter: toolDependencies.appleContext.xcodeProjectInterpreter,
  ),
  ConfigCommand(
    verboseHelp: verboseHelp,
    androidContext: toolDependencies.androidContext,
    toolContext: toolDependencies.toolContext,
    featureFlags: featureFlags,
    extensionManager: extensionManager,
  ),
  CustomDevicesCommand(featureFlags: featureFlags, toolContext: toolDependencies.toolContext),
  CreateCommand(
    androidContext: toolDependencies.androidContext,
    appleContext: toolDependencies.appleContext,
    templateRenderer: const MustacheTemplateRenderer(),
    toolContext: toolDependencies.toolContext,
    extensionTemplateManager: extensionTemplateManager,
    verboseHelp: verboseHelp,
  ),
  DaemonCommand(
    androidContext: toolDependencies.androidContext,
    androidWorkflow: android_workflow.androidWorkflow,
    deviceManager: globals.deviceManager,
    hidden: !verboseHelp,
    toolContext: toolDependencies.toolContext,
  ),
  DebugAdapterCommand(toolContext: toolDependencies.toolContext, verboseHelp: verboseHelp),
  DevicesCommand(
    deviceManager: globals.deviceManager!,
    doctor: globals.doctor!,
    toolContext: toolDependencies.toolContext,
    verboseHelp: verboseHelp,
  ),
  DoctorCommand(
    verbose: verbose,
    toolContext: toolDependencies.toolContext,
    // Provide the shared singleton from globals until dependent commands
    // (e.g. DevicesCommand, EmulatorsCommand) are migrated to DI.
    doctor: globals.doctor,
    extensionManager: extensionManager,
  ),
  DowngradeCommand(toolContext: toolDependencies.toolContext, verboseHelp: verboseHelp),
  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(
    doctor: toolDependencies.doctor,
    emulatorManager: toolDependencies.emulatorManager,
    toolContext: toolDependencies.toolContext,
    verboseHelp: verboseHelp,
  ),
  GenerateCommand(toolContext: toolDependencies.toolContext),
  GenerateLocalizationsCommand(toolContext: toolDependencies.toolContext),
  InstallCommand(toolContext: toolDependencies.toolContext, verboseHelp: verboseHelp),
  LogsCommand(toolContext: toolDependencies.toolContext),
  PackagesCommand(
    buildSystem: toolDependencies.buildSystem,
    toolContext: toolDependencies.toolContext,
    verboseHelp: verboseHelp,
  ),
  PrecacheCommand(
    verboseHelp: verboseHelp,
    cache: toolDependencies.toolContext.cache,
    logger: toolDependencies.toolContext.logger,
    platform: toolDependencies.toolContext.platform,
    featureFlags: featureFlags,
  ),
  RunCommand(verboseHelp: verboseHelp),
  ScreenshotCommand(toolContext: toolDependencies.toolContext),
  ShellCompletionCommand(toolContext: toolDependencies.toolContext),
  TestCommand(
    verboseHelp: verboseHelp,
    verbose: verbose,
    nativeAssetsBuilder: toolDependencies.toolContext.nativeAssetsBuilder,
  ),
  WidgetPreviewCommand(toolContext: toolDependencies.toolContext, verboseHelp: verboseHelp),
  UpgradeCommand(toolContext: toolDependencies.toolContext, verboseHelp: verboseHelp),
  SymbolizeCommand(toolContext: toolDependencies.toolContext),
  // Development-only commands. These are always hidden,
  IdeConfigCommand(toolContext: toolDependencies.toolContext),
  UpdatePackagesCommand(toolContext: toolDependencies.toolContext, 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 this._terminal,
    required this._stdio,
    required this._outputPreferences,
    this._stopwatchFactory = const StopwatchFactory(),
  });

  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,
        stdio: _stdio,
      );
    }
    if (daemon) {
      return NotifyingLogger(verbose: verbose, parent: logger);
    }
    if (machine) {
      return MachineOutputLogger(parent: logger);
    }
    return logger;
  }
}
