// Copyright (c) 2024, 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:async';
import 'dart:io' as io show exitCode, File, IOSink;

import 'package:args/args.dart' show ArgParser, ArgResults;
import 'package:front_end/src/api_unstable/vm.dart'
    show
        CompilerOptions,
        InvocationMode,
        CfeDiagnosticMessage,
        Verbosity,
        parseExperimentalArguments,
        parseExperimentalFlags,
        resolveInputUri;
import 'package:kernel/ast.dart' show Component;
import 'package:vm/kernel_front_end.dart'
    show
        badUsageExitCode,
        compileTimeErrorExitCode,
        compileToKernel,
        convertToPackageUri,
        createFrontEndFileSystem,
        createFrontEndTarget,
        ErrorDetector,
        ErrorPrinter,
        KernelCompilationArguments,
        parseCommandLineDefines,
        successExitCode,
        writeDepfile;
import 'package:vm/transformations/prefix_library_uris.dart'
    as prefix_library_uris;

import 'bytecode_serialization.dart' show BytecodeSizeStatistics;
import 'bytecode_generator.dart' show generateBytecode;
import 'options.dart' show BytecodeOptions;

final ArgParser _argParser = ArgParser(allowTrailingOptions: true)
  ..addOption(
    'platform',
    help: 'Path to vm_platform.dill file',
    defaultsTo: null,
  )
  ..addOption(
    'packages',
    help: 'Path to .dart_tool/package_config.json file',
    defaultsTo: null,
  )
  ..addOption(
    'output',
    abbr: 'o',
    help: 'Path to resulting bytecode file',
    defaultsTo: null,
  )
  ..addOption('depfile', help: 'Path to output Ninja depfile')
  ..addOption(
    'depfile-target',
    help: 'Override the target in the generated depfile',
    hide: true,
  )
  ..addMultiOption(
    'filesystem-root',
    help:
        'A base path for the multi-root virtual file system.'
        ' If multi-root file system is used, the input script and .dart_tool/package_config.json file should be specified using URI.',
  )
  ..addOption(
    'filesystem-scheme',
    help: 'The URI scheme for the multi-root virtual filesystem.',
  )
  ..addOption(
    'target',
    help: 'Target model that determines what core libraries are available',
    allowed: <String>['vm', 'flutter', 'flutter_runner', 'dart_runner'],
    defaultsTo: 'vm',
  )
  ..addMultiOption(
    'define',
    abbr: 'D',
    help: 'The values for the environment constants (e.g. -Dkey=value).',
  )
  ..addOption(
    'import-dill',
    help: 'Import libraries from existing dill file',
    defaultsTo: null,
  )
  ..addFlag(
    'enable-asserts',
    help: 'Whether asserts will be enabled.',
    defaultsTo: false,
  )
  ..addMultiOption(
    'bytecode-options',
    help: 'Specify options for bytecode generation:',
    valueHelp: 'opt1,opt2,...',
    allowed: BytecodeOptions.commandLineFlags.keys,
    allowedHelp: BytecodeOptions.commandLineFlags,
  )
  ..addMultiOption(
    'enable-experiment',
    help: 'Comma separated list of experimental features to enable.',
  )
  ..addFlag(
    'help',
    abbr: 'h',
    negatable: false,
    help: 'Print this help message.',
  )
  ..addFlag(
    'track-creation-locations',
    help:
        'Run a kernel transformer to track creation locations for'
        ' classes annotated with @pragma(\'track-creation-locations\').',
    defaultsTo: false,
    aliases: [
      // TODO(http://dartbug.com/63225): Remove this once flutter is migrated
      // to the new flag.
      'track-widget-creation',
    ],
  )
  ..addOption(
    'invocation-modes',
    help: 'Provides information to the front end about how it is invoked.',
    defaultsTo: '',
  )
  ..addOption(
    'validate',
    help:
        'Validate dynamic module against specified dynamic interface YAML file',
    defaultsTo: null,
  )
  ..addOption(
    'verbosity',
    help:
        'Sets the verbosity level used for filtering messages during '
        'compilation.',
    defaultsTo: Verbosity.defaultValue,
  )
  ..addOption(
    'prefix-library-uris',
    help: 'Slash-separated prefix to add to all library uris',
    defaultsTo: '',
  )
  ..addFlag(
    'allow-dynamic-calls-in-dynamic-modules',
    help: 'Allow dynamic calls in dynamic modules',
    defaultsTo: false,
  )
  ..addMultiOption(
    'extra-selectors-allowed-in-dynamic-calls',
    help:
        'Selector names that weren\'t exposed by the host, but are allowed in '
        'dynamic calls within the dynamic module',
  );

final String _usage =
    '''
Usage: dart2bytecode --platform vm_platform.dill [--import-dill host_app.dill] [--validate dynamic_interface.yaml] [options] input.dart
Compiles Dart sources to Dart bytecode.

Options:
${_argParser.usage}
''';

Future<void> main(List<String> arguments) async {
  io.exitCode = await runCompilerWithCommandLineArguments(arguments);
}

/// Run bytecode compiler tool with given [arguments]
/// and return exit code (0 on success, non-zero on failure).
Future<int> runCompilerWithCommandLineArguments(List<String> arguments) async {
  final ArgResults options = _argParser.parse(arguments);
  final String? platformKernel = options['platform'];

  if (options['help']) {
    print(_usage);
    return successExitCode;
  }

  final String? input = options.rest.singleOrNull;
  if (input == null || platformKernel == null) {
    print(_usage);
    return badUsageExitCode;
  }

  final String outputFileName = options['output'] ?? "$input.bytecode";
  final String? packages = options['packages'];
  final String targetName = options['target'];
  final String? fileSystemScheme = options['filesystem-scheme'];
  final String? depfile = options['depfile'];
  final String? depfileTarget = options['depfile-target'];
  final List<String>? fileSystemRoots = options['filesystem-root'];
  final bool enableAsserts = options['enable-asserts'];
  final List<String>? experimentalFlags = options['enable-experiment'];
  final Map<String, String> environmentDefines = {};

  if (!parseCommandLineDefines(options['define'], environmentDefines, _usage)) {
    return badUsageExitCode;
  }

  final String? importDill = options['import-dill'];
  final String? validateDynamicInterface = options['validate'];
  final String messageVerbosity = options['verbosity'];
  final String cfeInvocationModes = options['invocation-modes'];
  final bool trackCreationLocations = options['track-creation-locations'];
  final List<String>? bytecodeGeneratorOptions = options['bytecode-options'];
  final String libraryUrisPrefix = options['prefix-library-uris']!;
  final bool allowDynamicCallsInDynamicModules =
      options['allow-dynamic-calls-in-dynamic-modules'];
  final List<String> dynamicCallsSelectorAllowList =
      options['extra-selectors-allowed-in-dynamic-calls'];

  return await runCompilerWithOptions(
    input: input,
    platformKernel: platformKernel,
    outputFileName: outputFileName,
    targetName: targetName,
    packages: packages,
    importDill: importDill,
    validateDynamicInterface: validateDynamicInterface,
    enableAsserts: enableAsserts,
    experimentalFlags: experimentalFlags,
    environmentDefines: environmentDefines,
    fileSystemScheme: fileSystemScheme,
    fileSystemRoots: fileSystemRoots,
    messageVerbosity: messageVerbosity,
    cfeInvocationModes: cfeInvocationModes,
    trackCreationLocations: trackCreationLocations,
    bytecodeGeneratorOptions: bytecodeGeneratorOptions,
    depfile: depfile,
    depfileTarget: depfileTarget,
    libraryUrisPrefix: libraryUrisPrefix,
    allowDynamicCallsInDynamicModules: allowDynamicCallsInDynamicModules,
    dynamicCallsSelectorAllowList: dynamicCallsSelectorAllowList,
  );
}

/// Run bytecode compiler tool with given options
/// and return exit code (0 on success, non-zero on failure).
Future<int> runCompilerWithOptions({
  required String input,
  required String platformKernel,
  required String outputFileName,
  required String targetName,
  String? packages,
  String? importDill,
  String? validateDynamicInterface,
  bool enableAsserts = false,
  List<String>? experimentalFlags,
  Map<String, String> environmentDefines = const {},
  String? fileSystemScheme,
  List<String>? fileSystemRoots,
  String messageVerbosity = Verbosity.defaultValue,
  void Function(String) printMessage = print,
  String cfeInvocationModes = '',
  bool trackCreationLocations = false,
  List<String>? bytecodeGeneratorOptions,
  String? depfile,
  String? depfileTarget,
  required String libraryUrisPrefix,
  bool allowDynamicCallsInDynamicModules = false,
  List<String> dynamicCallsSelectorAllowList = const [],
}) async {
  final fileSystem = createFrontEndFileSystem(
    fileSystemScheme,
    fileSystemRoots,
  );

  final Uri? packagesUri = packages != null ? resolveInputUri(packages) : null;

  final platformKernelUri = Uri.base.resolveUri(new Uri.file(platformKernel));

  final List<Uri> additionalDillModules = <Uri>[];
  if (importDill != null) {
    additionalDillModules.add(Uri.base.resolveUri(new Uri.file(importDill)));
  }

  final Uri? dynamicInterfaceSpecificationUri =
      (validateDynamicInterface != null)
      ? resolveInputUri(validateDynamicInterface)
      : null;

  final verbosity = Verbosity.parseArgument(messageVerbosity);
  final errorPrinter = ErrorPrinter(verbosity, println: printMessage);
  final errorDetector = ErrorDetector(previousErrorHandler: errorPrinter.call);

  Uri mainUri = resolveInputUri(input);
  if (packagesUri != null) {
    mainUri = await convertToPackageUri(fileSystem, mainUri, packagesUri);
  }

  final BytecodeOptions bytecodeOptions = BytecodeOptions(
    enableAsserts: enableAsserts,
  )..parseCommandLineFlags(bytecodeGeneratorOptions);

  final CompilerOptions compilerOptions = CompilerOptions()
    ..sdkSummary = platformKernelUri
    ..fileSystem = fileSystem
    ..additionalDillModules = additionalDillModules
    ..packagesFileUri = packagesUri
    ..dynamicInterfaceSpecificationUri = dynamicInterfaceSpecificationUri
    ..allowDynamicCallsInDynamicModules = allowDynamicCallsInDynamicModules
    ..dynamicCallsSelectorAllowList = dynamicCallsSelectorAllowList
    ..explicitExperimentalFlags = parseExperimentalFlags(
      parseExperimentalArguments(experimentalFlags),
      onError: printMessage,
    )
    ..onDiagnostic = (CfeDiagnosticMessage m) {
      errorDetector(m);
    }
    ..embedSourceText = bytecodeOptions.embedSourceText
    ..invocationModes = InvocationMode.parseArguments(cfeInvocationModes)
    ..verbosity = verbosity
    ..target = createFrontEndTarget(
      targetName,
      trackCreationLocations: trackCreationLocations,
      supportMirrors: false,
      isClosureContextLoweringEnabled:
          bytecodeOptions.isClosureContextLoweringEnabled,
    );

  if (compilerOptions.target == null) {
    printMessage('Failed to create front-end target $targetName.');
    return badUsageExitCode;
  }

  final results = await compileToKernel(
    KernelCompilationArguments(
      source: mainUri,
      options: compilerOptions,
      requireMain: false,
      includePlatform: false,
      environmentDefines: Map.of(environmentDefines),
      enableAsserts: enableAsserts,
    ),
  );

  errorPrinter.printCompilationMessages();

  Component? component = results.component;
  if (errorDetector.hasCompilationErrors || component == null) {
    return compileTimeErrorExitCode;
  }
  component = prefix_library_uris.prefixLibraryUris(
    component,
    results.loadedLibraries,
    libraryUrisPrefix,
  );
  if (bytecodeOptions.showBytecodeSizeStatistics) {
    BytecodeSizeStatistics.reset();
  }
  final io.IOSink sink = io.File(outputFileName).openWrite();
  generateBytecode(
    component,
    sink,
    libraries: component.libraries
        .where((lib) => !results.loadedLibraries.contains(lib))
        .toList(),
    hierarchy: results.classHierarchy!,
    coreTypes: results.coreTypes!,
    options: bytecodeOptions,
    target: compilerOptions.target!,
    extraLoadedLibraries: results.loadedLibraries,
  );
  await sink.close();
  if (bytecodeOptions.showBytecodeSizeStatistics) {
    BytecodeSizeStatistics.dump();
  }

  if (depfile != null) {
    await writeDepfile(
      fileSystem,
      results.compiledSources!,
      depfileTarget ?? outputFileName,
      depfile,
    );
  }

  return successExitCode;
}
