// 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(toolContext: toolDependencies.toolContext, verboseHelp: verboseHelp),
  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(toolContext: toolDependencies.toolContext, verboseHelp: verboseHelp),
  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(toolContext: toolDependencies.toolContext, 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;
  }
}
