// 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. Pass "*" to allow all dynamic '
        'calls, which is unsafe and may result in runtime errors if target of a '
        'dynamic call is not from a dynamic module and not listed as '
        'dynamically-callable in the dynamic interface.',
  );

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;
}
