// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:io' show exit;

import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
import 'package:_fe_analyzer_shared/src/util/options.dart';
import 'package:_fe_analyzer_shared/src/util/resolve_input_uri.dart'
    show resolveInputUri;
import 'package:build_integration/file_system/single_root.dart'
    show SingleRootFileSystem;
import 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/api_prototype/experimental_flags.dart'
    show ExperimentalFlag;
import 'package:front_end/src/api_prototype/file_system.dart' show FileSystem;
import 'package:front_end/src/api_prototype/standard_file_system.dart'
    show StandardFileSystem;
import 'package:front_end/src/api_prototype/terminal_color_support.dart';
import 'package:front_end/src/base/command_line_options.dart';
import 'package:front_end/src/base/compiler_context.dart' show CompilerContext;
import 'package:front_end/src/base/file_system_dependency_tracker.dart';
import 'package:front_end/src/base/problems.dart' show DebugAbort;
import 'package:front_end/src/base/processed_options.dart'
    show ProcessedOptions;
import 'package:front_end/src/codes/cfe_codes.dart'
    show
        Message,
        PlainAndColorizedString,
        messageFastaUsageLong,
        messageFastaUsageShort,
        templateUnspecified;
import 'package:front_end/src/compute_platform_binaries_location.dart'
    show computePlatformBinariesLocation, computePlatformDillName;
import 'package:front_end/src/scheme_based_file_system.dart'
    show SchemeBasedFileSystem;
import 'package:kernel/target/targets.dart'
    show Target, TargetFlags, TestTargetFlags, getTarget, targets;

// Before adding new options here, you must:
//  * Document the option.
//  * Get an explicit approval from the front-end team.
const List<Option> optionSpecification = [
  Options.compileSdk,
  Options.dumpIr,
  Options.showOffsets,
  Options.enableExperiment,
  Options.enableUnscheduledExperiments,
  Options.excludeSource,
  Options.omitPlatform,
  Options.fatal,
  Options.fatalSkip,
  Options.forceLateLowering,
  Options.forceLateLoweringSentinel,
  Options.forceStaticFieldLowering,
  Options.forceNoExplicitGetterCalls,
  Options.forceConstructorTearOffLowering,
  Options.help,
  Options.librariesJson,
  Options.noDefines,
  Options.output,
  Options.packages,
  Options.platform,
  Options.sdk,
  Options.singleRootBase,
  Options.singleRootScheme,
  Options.nnbdWeakMode,
  Options.nnbdStrongMode,
  Options.target,
  Options.verbose,
  Options.verbosity,
  Options.verify,
  Options.skipPlatformVerification,
  Options.linkDependencies,
  Options.noDeps,
  Options.invocationModes,
  Options.defines,
];

void throwCommandLineProblem(String message) {
  throw new CommandLineProblem.deprecated(message);
}

ProcessedOptions analyzeCommandLine(
    FileSystemDependencyTracker? tracker,
    String programName,
    ParsedOptions parsedOptions,
    bool areRestArgumentsInputs) {
  final List<String> arguments = parsedOptions.arguments;

  final bool help = Options.help.read(parsedOptions);

  final bool verbose = Options.verbose.read(parsedOptions);

  if (help) {
    print(computeUsage(programName, verbose).problemMessage);
    exit(0);
  }

  if (parsedOptions.options.containsKey(Flags.compileSdk) &&
      parsedOptions.options.containsKey(Flags.platform)) {
    return throw new CommandLineProblem.deprecated(
        "Can't specify both '${Flags.compileSdk}' and '${Flags.platform}'.");
  }

  final String targetName = Options.target.read(parsedOptions);

  Map<ExperimentalFlag, bool> explicitExperimentalFlags =
      parseExperimentalFlags(
          parseExperimentalArguments(
              Options.enableExperiment.read(parsedOptions)),
          onError: throwCommandLineProblem,
          onWarning: print);

  final TargetFlags flags = new TestTargetFlags(
      forceLateLoweringsForTesting:
          Options.forceLateLowering.read(parsedOptions),
      forceStaticFieldLoweringForTesting:
          Options.forceStaticFieldLowering.read(parsedOptions),
      forceNoExplicitGetterCallsForTesting:
          Options.forceNoExplicitGetterCalls.read(parsedOptions),
      forceConstructorTearOffLoweringForTesting:
          Options.forceConstructorTearOffLowering.read(parsedOptions),
      forceLateLoweringSentinelForTesting:
          Options.forceLateLoweringSentinel.read(parsedOptions));

  final Target? target = getTarget(targetName, flags);
  if (target == null) {
    return throw new CommandLineProblem.deprecated(
        "Target '${targetName}' not recognized. "
        "Valid targets are:\n  ${targets.keys.join("\n  ")}");
  }

  final bool noDefines = Options.noDefines.read(parsedOptions);

  final bool noDeps = Options.noDeps.read(parsedOptions);

  final bool verify = Options.verify.read(parsedOptions);

  final bool skipPlatformVerification =
      Options.skipPlatformVerification.read(parsedOptions);

  final bool showOffsets = Options.showOffsets.read(parsedOptions);

  final bool dumpIr = Options.dumpIr.read(parsedOptions) || showOffsets;

  final bool excludeSource = Options.excludeSource.read(parsedOptions);

  final bool omitPlatform = Options.omitPlatform.read(parsedOptions);

  final Uri? packages = Options.packages.read(parsedOptions);

  final Set<String> fatal =
      new Set<String>.from(Options.fatal.read(parsedOptions) ?? <String>[]);

  final bool errorsAreFatal = fatal.contains("errors");

  final bool warningsAreFatal = fatal.contains("warnings");

  final int fatalSkip =
      int.tryParse(Options.fatalSkip.read(parsedOptions) ?? "0") ?? -1;

  final bool compileSdk = Options.compileSdk.read(parsedOptions) != null;

  final String? singleRootScheme = Options.singleRootScheme.read(parsedOptions);
  final Uri? singleRootBase = Options.singleRootBase.read(parsedOptions);

  final bool enableUnscheduledExperiments =
      Options.enableUnscheduledExperiments.read(parsedOptions);

  final List<Uri> linkDependencies =
      Options.linkDependencies.read(parsedOptions) ?? [];

  final String invocationModes =
      Options.invocationModes.read(parsedOptions) ?? '';

  final String verbosity = Options.verbosity.read(parsedOptions);

  FileSystem fileSystem;
  if (tracker != null) {
    fileSystem = StandardFileSystem.instanceWithTracking(tracker);
  } else {
    fileSystem = StandardFileSystem.instance;
  }
  if (singleRootScheme != null) {
    fileSystem = new SchemeBasedFileSystem({
      'file': fileSystem,
      'data': fileSystem,
      // TODO(askesc): remove also when fixing StandardFileSystem (empty schemes
      // should have been handled elsewhere).
      '': fileSystem,
      singleRootScheme: new SingleRootFileSystem(
          singleRootScheme, singleRootBase!, fileSystem),
    });
  }

  // In order to facilitate the roll out of CFE constants on Dart2js, we need to
  // be able to support both passing '--no-defines' and also evaluating CFE
  // constants when the target supports it. This is so we can easily enable or
  // disable fully evaluating constants in the CFE with a flag. This can be
  // deleted when the CFE fully evaluates constants for Dart2js in all cases.
  Map<String, String>? environmentDefines;
  if (noDefines && target.constantsBackend.supportsUnevaluatedConstants) {
    // Pass a null environment.
  } else {
    environmentDefines = parsedOptions.defines;
  }

  CompilerOptions compilerOptions = new CompilerOptions()
    ..compileSdk = compileSdk
    ..fileSystem = fileSystem
    ..packagesFileUri = packages
    ..target = target
    ..throwOnErrorsForDebugging = errorsAreFatal
    ..throwOnWarningsForDebugging = warningsAreFatal
    ..skipForDebugging = fatalSkip
    ..embedSourceText = !excludeSource
    ..debugDump = dumpIr
    ..debugDumpShowOffsets = showOffsets
    ..omitPlatform = omitPlatform
    ..verbose = verbose
    ..verify = verify
    ..skipPlatformVerification = skipPlatformVerification
    ..explicitExperimentalFlags = explicitExperimentalFlags
    ..environmentDefines = environmentDefines
    ..enableUnscheduledExperiments = enableUnscheduledExperiments
    ..additionalDills = linkDependencies
    ..emitDeps = !noDeps
    ..invocationModes = InvocationMode.parseArguments(invocationModes)
    ..verbosity = Verbosity.parseArgument(verbosity);

  if (programName == "compile_platform") {
    if (arguments.length != 5) {
      return throw new CommandLineProblem.deprecated(
          "Expected five arguments.");
    }
    if (compileSdk) {
      return throw new CommandLineProblem.deprecated(
          "Cannot specify '${Flags.compileSdk}' option to compile_platform.");
    }
    if (parsedOptions.options.containsKey(Flags.output)) {
      return throw new CommandLineProblem.deprecated(
          "Cannot specify '${Flags.output}' option to compile_platform.");
    }

    return new ProcessedOptions(
        options: compilerOptions
          ..sdkSummary = Options.platform.read(parsedOptions)
          ..librariesSpecificationUri = resolveInputUri(arguments[1])
          ..setExitCodeOnProblem = true,
        inputs: arguments[0].split(',').map(Uri.parse).toList(),
        output: resolveInputUri(arguments[3]));
  } else if (arguments.isEmpty) {
    return throw new CommandLineProblem.deprecated("No Dart file specified.");
  }

  final Uri defaultOutput = resolveInputUri("${arguments.first}.dill");

  final Uri output = Options.output.read(parsedOptions) ?? defaultOutput;

  final Uri? sdk =
      Options.sdk.read(parsedOptions) ?? Options.compileSdk.read(parsedOptions);

  final Uri? librariesJson = Options.librariesJson.read(parsedOptions);

  final Uri? platform = compileSdk
      ? null
      : (Options.platform.read(parsedOptions) ??
          computePlatformBinariesLocation(forceBuildDir: true)
              .resolve(computePlatformDillName(target, () {
            throwCommandLineProblem(
                "Target '${target.name}' requires an explicit "
                "'${Flags.platform}' option.");
          })!));
  compilerOptions
    ..sdkRoot = sdk
    ..sdkSummary = platform
    ..librariesSpecificationUri = librariesJson;

  List<Uri> inputs = <Uri>[];
  if (areRestArgumentsInputs) {
    for (String argument in arguments) {
      inputs.add(resolveInputUri(argument));
    }
  }
  return new ProcessedOptions(
      options: compilerOptions, inputs: inputs, output: output);
}

Future<T> withGlobalOptions<T>(
    String programName,
    List<String> arguments,
    bool areRestArgumentsInputs,
    Future<T> f(CompilerContext context, List<String> restArguments),
    {FileSystemDependencyTracker? tracker}) {
  ParsedOptions? parsedOptions;
  ProcessedOptions options;
  CommandLineProblem? problem;
  try {
    parsedOptions = ParsedOptions.parse(arguments, optionSpecification);
    options = analyzeCommandLine(
        tracker, programName, parsedOptions, areRestArgumentsInputs);
  } on CommandLineProblem catch (e) {
    options = new ProcessedOptions();
    problem = e;
  }

  return CompilerContext.runWithOptions<T>(options, (CompilerContext c) {
    if (problem != null) {
      print(computeUsage(programName, options.verbose).problemMessage);
      PlainAndColorizedString formatted =
          c.format(problem.message.withoutLocation(), Severity.error);
      String formattedText;
      if (enableColors) {
        formattedText = formatted.colorized;
      } else {
        formattedText = formatted.plain;
      }
      print(formattedText);
      exit(1);
    }

    return f(c, parsedOptions!.arguments);
  }, errorOnMissingInput: problem == null);
}

Message computeUsage(String programName, bool verbose) {
  String basicUsage = "Usage: $programName [options] dartfile\n";
  String? summary;
  String options = (verbose
          ? messageFastaUsageLong.problemMessage
          : messageFastaUsageShort.problemMessage)
      .trim();
  switch (programName) {
    case "outline":
      summary =
          "Creates an outline of a Dart program in the Dill/Kernel IR format.";
      break;

    case "compile":
      summary = "Compiles a Dart program to the Dill/Kernel IR format.";
      break;

    case "run":
      summary = "Runs a Dart program.";
      break;

    case "compile_platform":
      summary = "Compiles Dart SDK platform to the Dill/Kernel IR format.";
      basicUsage = "Usage: $programName [options]"
          " dart-library-uri libraries.json vm_outline.dill"
          " platform.dill outline.dill\n";
  }
  StringBuffer sb = new StringBuffer(basicUsage);
  if (summary != null) {
    sb.writeln();
    sb.writeln(summary);
    sb.writeln();
  }
  sb.write(options);
  // TODO(ahe): Don't use [templateUnspecified].
  return templateUnspecified.withArguments("$sb");
}

Future<T> runProtectedFromAbort<T>(Future<T> Function() action,
    [T? failingValue]) async {
  try {
    return await action();
  } on DebugAbort catch (e) {
    print(e.message.problemMessage);

    // DebugAbort should never happen in production code, so we want test.py to
    // treat this as a crash which is signalled by exiting with 255.
    exit(255);
  }
}
