// 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 CfeSeverity;
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,
        codeFastaUsageLong,
        codeFastaUsageShort,
        codeUnspecified;
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(),
        CfeSeverity.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
              ? codeFastaUsageLong.problemMessage
              : codeFastaUsageShort.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 [codeUnspecified].
  return codeUnspecified.withArgumentsOld("$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);
  }
}
