// Copyright (c) 2019, 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';

import 'package:args/args.dart';
import 'package:dart2native/generate.dart';
import 'package:dart2wasm/generate_wasm.dart';
import 'package:front_end/src/api_prototype/compiler_options.dart'
    show Verbosity;
import 'package:path/path.dart' as path;
import 'package:vm/target_os.dart'; // For possible --target-os values.

import '../core.dart';
import '../experiments.dart';
import '../native_assets.dart';
import '../sdk.dart';
import '../utils.dart';
import '../vm_interop_handler.dart';

// The unique place where we store dart2wasm binaryen flags.
//
// Other uses (e.g. in shell scripts) will grep in this file for the flags. So
// please keep it as a simple multi-line string of flags.
final List<String> binaryenFlags = '''
  --all-features
  --closed-world
  --traps-never-happen
  --type-unfinalizing
  -O3
  --type-ssa
  --gufa
  -O3
  --type-merging
  -O1
  --type-finalizing
''' // end of binaryenFlags
    .split('\n')
    .map((line) => line.trim())
    .where((line) => line.isNotEmpty)
    .toList();

const int compileErrorExitCode = 64;

class Option {
  final String flag;
  final String help;
  final String? abbr;
  final String? defaultsTo;
  final bool? flagDefaultsTo;
  final String? valueHelp;
  final List<String>? allowed;
  final Map<String, String>? allowedHelp;

  const Option({
    required this.flag,
    required this.help,
    this.abbr,
    this.defaultsTo,
    this.flagDefaultsTo,
    this.valueHelp,
    this.allowed,
    this.allowedHelp,
  });
}

bool checkFile(String sourcePath) {
  if (!FileSystemEntity.isFileSync(sourcePath)) {
    stderr.writeln('"$sourcePath" file not found.');
    stderr.flush();
    return false;
  }
  return true;
}

class CompileJSCommand extends CompileSubcommandCommand {
  static const String cmdName = 'js';

  /// Accept all flags so we can delegate arg parsing to dart2js internally.
  @override
  final ArgParser argParser = ArgParser.allowAnything();

  CompileJSCommand({bool verbose = false})
      : super(cmdName, 'Compile Dart to JavaScript.', verbose);

  @override
  String get invocation => '${super.invocation} <dart entry point>';

  @override
  FutureOr<int> run() async {
    if (!Sdk.checkArtifactExists(sdk.dart2jsSnapshot)) return 255;

    final librariesPath = path.absolute(sdk.sdkPath, 'lib', 'libraries.json');

    if (!Sdk.checkArtifactExists(librariesPath)) return 255;

    VmInteropHandler.run(
      sdk.dart2jsSnapshot,
      [
        '--libraries-spec=$librariesPath',
        '--cfe-invocation-modes=compile',
        '--invoker=dart_cli',
        ...argResults!.arguments,
      ],
      packageConfigOverride: null,
    );

    return 0;
  }
}

class CompileSnapshotCommand extends CompileSubcommandCommand {
  static const String jitSnapshotCmdName = 'jit-snapshot';
  static const String kernelCmdName = 'kernel';

  final String commandName;
  final String help;
  final String fileExt;
  final String formatName;

  CompileSnapshotCommand({
    required this.commandName,
    required this.help,
    required this.fileExt,
    required this.formatName,
    bool verbose = false,
  }) : super(commandName, 'Compile Dart $help', verbose) {
    argParser
      ..addOption(
        outputFileOption.flag,
        help: outputFileOption.help,
        abbr: outputFileOption.abbr,
      )
      ..addOption(
        verbosityOption.flag,
        help: verbosityOption.help,
        abbr: verbosityOption.abbr,
        defaultsTo: verbosityOption.defaultsTo,
        allowed: verbosityOption.allowed,
        allowedHelp: verbosityOption.allowedHelp,
      )
      ..addOption(
        packagesOption.flag,
        abbr: packagesOption.abbr,
        valueHelp: packagesOption.valueHelp,
        help: packagesOption.help,
      )
      ..addMultiOption(
        defineOption.flag,
        help: defineOption.help,
        abbr: defineOption.abbr,
        valueHelp: defineOption.valueHelp,
      )
      ..addFlag(soundNullSafetyOption.flag,
          help: soundNullSafetyOption.help,
          defaultsTo: soundNullSafetyOption.flagDefaultsTo,
          hide: true)
      ..addExperimentalFlags(verbose: verbose);
  }

  @override
  String get invocation {
    String msg = '${super.invocation} <dart entry point>';
    if (isJitSnapshot) {
      msg += ' [<training arguments>]';
    }
    return msg;
  }

  @override
  ArgParser createArgParser() {
    return ArgParser(
      // Don't parse the training arguments for JIT snapshots, but don't accept
      // flags after the script name for kernel snapshots.
      allowTrailingOptions: !isJitSnapshot,
      usageLineLength: dartdevUsageLineLength,
    );
  }

  bool get isJitSnapshot => commandName == jitSnapshotCmdName;

  @override
  FutureOr<int> run() async {
    final args = argResults!;
    if (args.rest.isEmpty) {
      // This throws.
      usageException('Missing Dart entry point.');
    } else if (!isJitSnapshot && args.rest.length > 1) {
      usageException('Unexpected arguments after Dart entry point.');
    }

    final String sourcePath = args.rest[0];
    if (!checkFile(sourcePath)) {
      return -1;
    }

    // Determine output file name.
    String? outputFile = args[outputFileOption.flag];
    if (outputFile == null) {
      final inputWithoutDart = sourcePath.endsWith('.dart')
          ? sourcePath.substring(0, sourcePath.length - 5)
          : sourcePath;
      outputFile = '$inputWithoutDart.$fileExt';
    }

    final enabledExperiments = args.enabledExperiments;
    final environmentVars = args['define'] ?? <String, String>{};

    // Build arguments.
    final buildArgs = <String>[];
    buildArgs.add('--snapshot-kind=$formatName');
    buildArgs.add('--snapshot=${path.canonicalize(outputFile)}');

    final bool soundNullSafety = args['sound-null-safety'];
    if (!soundNullSafety) {
      if (!shouldAllowNoSoundNullSafety()) {
        return compileErrorExitCode;
      }
      buildArgs.add('--no-sound-null-safety');
    }

    final String? packages = args[packagesOption.flag];
    if (packages != null) {
      buildArgs.add('--packages=$packages');
    }

    final String? verbosity = args[verbosityOption.flag];
    buildArgs.add('--verbosity=$verbosity');

    if (enabledExperiments.isNotEmpty) {
      buildArgs.add("--enable-experiment=${enabledExperiments.join(',')}");
    }
    if (verbose) {
      buildArgs.add('-v');
    }
    if (environmentVars.isNotEmpty) {
      buildArgs.addAll(environmentVars.map<String>((e) => '--define=$e'));
    }
    buildArgs.add(path.canonicalize(sourcePath));

    // Add the training arguments.
    if (args.rest.length > 1) {
      buildArgs.addAll(args.rest.sublist(1));
    }

    log.stdout('Compiling $sourcePath to $commandName file $outputFile.');
    // TODO(bkonyi): perform compilation in same process.
    final process = await startDartProcess(sdk, buildArgs);
    routeToStdout(process);
    return process.exitCode;
  }
}

class CompileNativeCommand extends CompileSubcommandCommand {
  static const String exeCmdName = 'exe';
  static const String aotSnapshotCmdName = 'aot-snapshot';

  final String commandName;
  final String format;
  final String help;
  final bool nativeAssetsExperimentEnabled;

  CompileNativeCommand({
    required this.commandName,
    required this.format,
    required this.help,
    bool verbose = false,
    this.nativeAssetsExperimentEnabled = false,
  }) : super(commandName, 'Compile Dart $help', verbose) {
    argParser
      ..addOption(
        outputFileOption.flag,
        help: outputFileOption.help,
        abbr: outputFileOption.abbr,
      )
      ..addOption(
        verbosityOption.flag,
        help: verbosityOption.help,
        abbr: verbosityOption.abbr,
        defaultsTo: verbosityOption.defaultsTo,
        allowed: verbosityOption.allowed,
        allowedHelp: verbosityOption.allowedHelp,
      )
      ..addMultiOption(
        defineOption.flag,
        help: defineOption.help,
        abbr: defineOption.abbr,
        valueHelp: defineOption.valueHelp,
      );
    argParser
      ..addOption(
        packagesOption.flag,
        abbr: packagesOption.abbr,
        valueHelp: packagesOption.valueHelp,
        help: packagesOption.help,
      )
      ..addFlag(soundNullSafetyOption.flag,
          help: soundNullSafetyOption.help,
          defaultsTo: soundNullSafetyOption.flagDefaultsTo,
          hide: true)
      ..addOption('save-debugging-info', abbr: 'S', valueHelp: 'path', help: '''
Remove debugging information from the output and save it separately to the specified file.
<path> can be relative or absolute.''')
      ..addMultiOption(
        'extra-gen-snapshot-options',
        help: 'Pass additional options to gen_snapshot.',
        hide: true,
        valueHelp: 'opt1,opt2,...',
      )
      ..addOption('target-os',
          help: 'Compile to a specific target operating system.',
          allowed: TargetOS.names)
      ..addExperimentalFlags(verbose: verbose);
  }

  @override
  String get invocation => '${super.invocation} <dart entry point>';

  @override
  FutureOr<int> run() async {
    // AOT compilation isn't supported on ia32. Currently, generating an
    // executable only supports AOT runtimes, so these commands are disabled.
    if (Platform.version.contains('ia32')) {
      stderr.write(
          "'dart compile $commandName' is not supported on x86 architectures.\n");
      return 64;
    }
    if (!Sdk.checkArtifactExists(genKernel) ||
        !Sdk.checkArtifactExists(genSnapshot)) {
      return 255;
    }
    final args = argResults!;

    // We expect a single rest argument; the dart entry point.
    if (args.rest.length != 1) {
      // This throws.
      usageException('Missing Dart entry point.');
    }
    final String sourcePath = args.rest[0];
    if (!checkFile(sourcePath)) {
      return -1;
    }

    if (!args['sound-null-safety'] && !shouldAllowNoSoundNullSafety()) {
      return compileErrorExitCode;
    }

    if (!nativeAssetsExperimentEnabled) {
      if (await warnOnNativeAssets()) {
        return 255;
      }
    } else {
      final (success, assets) = await compileNativeAssetsJit(verbose: verbose);
      if (!success) {
        stderr.writeln('Native assets build failed.');
        return 255;
      }
      if (assets.isNotEmpty) {
        stderr.writeln(
            "'dart compile' does currently not support native assets.");
        return 255;
      }
    }

    String? targetOS = args['target-os'];
    if (format != 'exe') {
      assert(format == 'aot');
      // If we're generating an AOT snapshot and not an executable, then
      // targetOS is allowed to be null for a platform-independent snapshot
      // or a different platform than the host.
    } else if (targetOS == null) {
      targetOS = Platform.operatingSystem;
    } else if (targetOS != Platform.operatingSystem) {
      stderr.writeln(
          "'dart compile $commandName' does not support cross-OS compilation.");
      stderr.writeln('Host OS: ${Platform.operatingSystem}');
      stderr.writeln('Target OS: $targetOS');
      return 128;
    }

    try {
      await generateNative(
        kind: format,
        sourceFile: sourcePath,
        outputFile: args['output'],
        defines: args['define'],
        packages: args['packages'],
        enableExperiment: args.enabledExperiments.join(','),
        soundNullSafety: args['sound-null-safety'],
        debugFile: args['save-debugging-info'],
        verbose: verbose,
        verbosity: args['verbosity'],
        extraOptions: args['extra-gen-snapshot-options'],
        targetOS: targetOS,
      );
      return 0;
    } catch (e, st) {
      log.stderr('Error: AOT compilation failed');
      log.stderr(e.toString());
      if (verbose) {
        log.stderr(st.toString());
      }
      return compileErrorExitCode;
    }
  }
}

class CompileWasmCommand extends CompileSubcommandCommand {
  static const String commandName = 'wasm';
  static const String format = 'wasm';
  static const String help =
      'Compile Dart to a WebAssembly/WasmGC module (EXPERIMENTAL).';

  final String optimizer = path.join(
      binDir.path, 'utils', Platform.isWindows ? 'wasm-opt.exe' : 'wasm-opt');

  CompileWasmCommand({bool verbose = false})
      : super(commandName, help, verbose, hidden: !verbose) {
    argParser
      ..addOption(
        outputFileOption.flag,
        help: outputFileOption.help,
        abbr: outputFileOption.abbr,
      )
      ..addFlag(
        'optimize',
        defaultsTo: true,
        negatable: true,
        help: 'Optimize wasm output using Binaryen wasm-opt.',
      )
      ..addFlag(
        'omit-type-checks',
        defaultsTo: false,
        negatable: false,
        help: 'Omit runtime type checks, such as covariance and downcasts.',
        hide: !verbose,
      )
      ..addFlag(
        'name-section',
        defaultsTo: false,
        negatable: false,
        help: 'Include a name section with printable function names.',
        hide: !verbose,
      )
      ..addFlag(
        'print-wasm',
        help: 'Print human-readable wasm debug output',
        hide: !verbose,
        negatable: false,
      )
      ..addFlag(
        'print-kernel',
        help: 'Print human-readable Dart kernel debug output',
        hide: !verbose,
        negatable: false,
      )
      ..addFlag(
        'verbose',
        abbr: 'v',
        help: 'Print debug output during compilation',
        negatable: false,
      )
      ..addFlag(
        'enable-asserts',
        help: 'Enable assert statements.',
        negatable: false,
      )
      ..addOption(
        'shared-memory',
        help: 'Import a shared memory buffer.'
            ' The max number of pages must be passed.',
        valueHelp: 'page count',
        hide: !verbose,
      )
      ..addOption(
        packagesOption.flag,
        abbr: packagesOption.abbr,
        valueHelp: packagesOption.valueHelp,
        help: packagesOption.help,
        hide: !verbose,
      );
// TODO(): Defines are currently not supported by dart2wasm.
//      ..addMultiOption(
//        defineOption.flag,
//        help: defineOption.help,
//        abbr: defineOption.abbr,
//        valueHelp: defineOption.valueHelp,
//      )
  }

  @override
  String get invocation => '${super.invocation} <dart entry point>';

  @override
  FutureOr<int> run() async {
    log.stdout('*NOTE*: Compilation to WasmGC is experimental.');
    log.stdout(
        'The support may change, or be removed, with no advance notice.\n');

    final libraries = path.absolute(sdk.sdkPath, 'lib', 'libraries.json');
    if (!Sdk.checkArtifactExists(libraries)) {
      return 255;
    }
    final args = argResults!;
    bool verbose = this.verbose || args['verbose'];
    if (args['optimize'] && !Sdk.checkArtifactExists(optimizer)) {
      return 255;
    }

    // We expect a single rest argument; the dart entry point.
    if (args.rest.length != 1) {
      // This throws.
      usageException('Missing Dart entry point.');
    }
    final String sourcePath = args.rest[0];
    if (!checkFile(sourcePath)) {
      return -1;
    }

    // Determine output file name.
    String? outputFile = args[outputFileOption.flag];
    if (outputFile == null) {
      final inputWithoutDart = sourcePath.endsWith('.dart')
          ? sourcePath.substring(0, sourcePath.length - 5)
          : sourcePath;
      outputFile = '$inputWithoutDart.wasm';
    }

    if (!outputFile.endsWith('.wasm')) {
      log.stderr(
          'Error: The output file "$outputFile" does not end with ".wasm"');
      return 255;
    }
    final outputFileBasename =
        outputFile.substring(0, outputFile.length - '.wasm'.length);

    final options = WasmCompilerOptions(
      mainUri: Uri.file(path.absolute(sourcePath)),
      outputFile: outputFile,
    );
    options.librariesSpecPath =
        Uri.file(path.absolute(sdk.sdkPath, 'lib', 'libraries.json'));
    options.sdkPath = Uri.file(path.absolute(sdk.sdkPath));
    options.packagesPath = args[packagesOption.flag];
    options.translatorOptions.enableAsserts = args['enable-asserts'];
    options.translatorOptions.printWasm = args['print-wasm'];
    options.translatorOptions.printKernel = args['print-kernel'];
    options.translatorOptions.omitTypeChecks = args['omit-type-checks'];
    options.translatorOptions.nameSection = args['name-section'];
    if (args['shared-memory'] != null) {
      int? maxPages = int.tryParse(args['shared-memory']);
      if (maxPages == null) {
        usageException(
            'Error: The --shared-memory flag must specify a number!');
      }
      options.translatorOptions.importSharedMemory = true;
      options.translatorOptions.sharedMemoryMaxPages = maxPages;
    }

    int result;
    try {
      result = await generateWasm(
        options,
        verbose: verbose,
        errorPrinter: (error) => log.stderr(error),
      );
      if (result != 0) return compileErrorExitCode;
    } catch (e, st) {
      log.stderr('Error: Wasm compilation failed');
      log.stderr(e.toString());
      if (verbose) {
        log.stderr(st.toString());
      }
      return compileErrorExitCode;
    }

    if (args['optimize']) {
      final unoptFile = '$outputFileBasename.unopt.wasm';
      File(outputFile).renameSync(unoptFile);

      final flags = [
        ...binaryenFlags,
        if (args['name-section']) '-g',
      ];

      if (verbose) {
        log.stdout('Optimizing output with: $optimizer $flags');
      }
      final processResult = Process.runSync(
        optimizer,
        [...flags, '-o', outputFile, unoptFile],
      );
      if (processResult.exitCode != 0) {
        log.stderr('Error: Wasm compilation failed while optimizing output');
        log.stderr(processResult.stderr);
        return compileErrorExitCode;
      }
    }

    final mjsFile = '$outputFileBasename.mjs';
    log.stdout(
        "Generated wasm module '$outputFile', and JS init file '$mjsFile'.");
    return result;
  }
}

abstract class CompileSubcommandCommand extends DartdevCommand {
  final outputFileOption = Option(
    flag: 'output',
    abbr: 'o',
    help: '''
Write the output to <file name>.
This can be an absolute or relative path.
''',
  );
  final verbosityOption = Option(
    flag: 'verbosity',
    help: '''
Sets the verbosity level of the compilation.
''',
    defaultsTo: Verbosity.defaultValue,
    allowed: Verbosity.allowedValues,
    allowedHelp: Verbosity.allowedValuesHelp,
  );
  final soundNullSafetyOption = Option(
    flag: 'sound-null-safety',
    help: 'DEPRECATED: Respect the nullability of types at runtime.',
    flagDefaultsTo: true,
  );

  late final Option defineOption;
  late final Option packagesOption;

  CompileSubcommandCommand(super.name, super.description, super.verbose,
      {super.hidden})
      : defineOption = Option(
          flag: 'define',
          abbr: 'D',
          valueHelp: 'key=value',
          help: '''
Define an environment declaration. To specify multiple declarations, use multiple options or use commas to separate key-value pairs.
For example: dart compile $name -Da=1,b=2 main.dart''',
        ),
        packagesOption = Option(
            flag: 'packages',
            abbr: 'p',
            valueHelp: 'path',
            help:
                '''Get package locations from the specified file instead of .dart_tool/package_config.json.
<path> can be relative or absolute.
For example: dart compile $name --packages=/tmp/pkgs.json main.dart''');

  bool shouldAllowNoSoundNullSafety() {
    // We need to maintain support for generating AOT snapshots and kernel
    // files with no-sound-null-safety internal Flutter aplications are
    // fully null-safe.
    //
    // See https://github.com/dart-lang/sdk/issues/51513 for context.
    if (name == CompileNativeCommand.aotSnapshotCmdName ||
        name == CompileSnapshotCommand.kernelCmdName) {
      log.stdout(
          'Warning: the flag --no-sound-null-safety is deprecated and pending removal.');
      return true;
    }
    log.stdout(
        'Error: the flag --no-sound-null-safety is not supported in Dart 3.');
    return false;
  }
}

class CompileCommand extends DartdevCommand {
  static const String cmdName = 'compile';
  CompileCommand({
    bool verbose = false,
    bool nativeAssetsExperimentEnabled = false,
  }) : super(cmdName, 'Compile Dart to various formats.', verbose) {
    addSubcommand(CompileJSCommand(verbose: verbose));
    addSubcommand(CompileSnapshotCommand(
      commandName: CompileSnapshotCommand.jitSnapshotCmdName,
      help: 'to a JIT snapshot.\n'
          'The executable will be run once to snapshot a warm JIT.\n'
          'To run the snapshot use: dart run <JIT file>',
      fileExt: 'jit',
      formatName: 'app-jit',
      verbose: verbose,
    ));
    addSubcommand(CompileSnapshotCommand(
      commandName: CompileSnapshotCommand.kernelCmdName,
      help: 'to a kernel snapshot.\n'
          'To run the snapshot use: dart run <kernel file>',
      fileExt: 'dill',
      formatName: 'kernel',
      verbose: verbose,
    ));
    addSubcommand(CompileNativeCommand(
      commandName: CompileNativeCommand.exeCmdName,
      help: 'to a self-contained executable.',
      format: 'exe',
      verbose: verbose,
      nativeAssetsExperimentEnabled: nativeAssetsExperimentEnabled,
    ));
    addSubcommand(CompileNativeCommand(
      commandName: CompileNativeCommand.aotSnapshotCmdName,
      help: 'to an AOT snapshot.\n'
          'To run the snapshot use: dartaotruntime <AOT snapshot file>',
      format: 'aot',
      verbose: verbose,
      nativeAssetsExperimentEnabled: nativeAssetsExperimentEnabled,
    ));
    addSubcommand(CompileWasmCommand(verbose: verbose));
  }
}
