// Copyright (c) 2020, 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:dart2native/generate.dart';
import 'package:path/path.dart' as path;

import '../core.dart';
import '../sdk.dart';
import '../vm_interop_handler.dart';

const int compileErrorExitCode = 64;

class Option {
  final String flag;
  final String help;
  final String abbr;

  Option({this.flag, this.help, this.abbr});
}

final Map<String, Option> commonOptions = {
  'outputFile': Option(
    flag: 'output',
    abbr: 'o',
    help: '''
Write the output to <file name>.
This can be an absolute or reletive path.
''',
  ),
};

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

  return true;
}

class CompileJSCommand extends DartdevCommand<int> {
  CompileJSCommand() : super('js', 'Compile Dart to JavaScript.') {
    argParser
      ..addOption(
        commonOptions['outputFile'].flag,
        help: commonOptions['outputFile'].help,
        abbr: commonOptions['outputFile'].abbr,
      )
      ..addFlag(
        'minified',
        help: 'Generate minified output.',
        abbr: 'm',
        negatable: false,
      );
  }

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

  @override
  FutureOr<int> run() async {
    if (!Sdk.checkArtifactExists(sdk.dart2jsSnapshot)) {
      return 255;
    }
    final String librariesPath = path.absolute(
      sdk.sdkPath,
      'lib',
      'libraries.json',
    );

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

    // We expect a single rest argument; the dart entry point.
    if (argResults.rest.length != 1) {
      // This throws.
      usageException('Missing Dart entry point.');
    }

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

    VmInteropHandler.run(sdk.dart2jsSnapshot, [
      '--libraries-spec=$librariesPath',
      ...argResults.arguments,
    ]);

    return 0;
  }
}

class CompileSnapshotCommand extends DartdevCommand<int> {
  final String commandName;
  final String help;
  final String fileExt;
  final String formatName;

  CompileSnapshotCommand({
    this.commandName,
    this.help,
    this.fileExt,
    this.formatName,
  }) : super(commandName, 'Compile Dart $help') {
    argParser
      ..addOption(
        commonOptions['outputFile'].flag,
        help: commonOptions['outputFile'].help,
        abbr: commonOptions['outputFile'].abbr,
      );
  }

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

  @override
  FutureOr<int> run() async {
    // We expect a single rest argument; the dart entry point.
    if (argResults.rest.length != 1) {
      // This throws.
      usageException('Missing Dart entry point.');
    }

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

    // Determine output file name.
    String outputFile = argResults[commonOptions['outputFile'].flag];
    if (outputFile == null) {
      final inputWithoutDart = sourcePath.replaceFirst(RegExp(r'\.dart$'), '');
      outputFile = '$inputWithoutDart.$fileExt';
    }

    // Build arguments.
    List<String> args = [];
    args.add('--snapshot-kind=$formatName');
    args.add('--snapshot=${path.canonicalize(outputFile)}');
    if (verbose) {
      args.add('-v');
    }
    args.add(path.canonicalize(sourcePath));

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

class CompileNativeCommand extends DartdevCommand<int> {
  final String commandName;
  final String format;
  final String help;

  CompileNativeCommand({
    this.commandName,
    this.format,
    this.help,
  }) : super(commandName, 'Compile Dart $help') {
    argParser
      ..addOption(
        commonOptions['outputFile'].flag,
        help: commonOptions['outputFile'].help,
        abbr: commonOptions['outputFile'].abbr,
      )
      ..addMultiOption('define', abbr: 'D', valueHelp: 'key=value', help: '''
Set values of environment variables. To specify multiple variables, use multiple options or use commas to separate key-value pairs.
For example, 'dart compile $commandName -Da=1,b=2 main.dart'.''')
      ..addFlag('enable-asserts',
          negatable: false, help: 'Enable assert statements.')
      ..addOption('packages',
          abbr: 'p',
          valueHelp: 'path',
          help:
              '''Get package locations from the specified file instead of .packages.
<path> can be relative or absolute.
For example, 'dart compile $commandName --packages=/tmp/pkgs main.dart'.''')
      ..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.''');
  }

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

  @override
  FutureOr<int> run() async {
    if (!Sdk.checkArtifactExists(genKernel) ||
        !Sdk.checkArtifactExists(genSnapshot)) {
      return 255;
    }
    // We expect a single rest argument; the dart entry point.
    if (argResults.rest.length != 1) {
      // This throws.
      usageException('Missing Dart entry point.');
    }

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

    try {
      await generateNative(
        kind: format,
        sourceFile: sourcePath,
        outputFile: argResults['output'],
        defines: argResults['define'],
        packages: argResults['packages'],
        enableAsserts: argResults['enable-asserts'],
        debugFile: argResults['save-debugging-info'],
        verbose: verbose,
      );
      return 0;
    } catch (e) {
      log.stderr('Error: AOT compilation failed');
      log.stderr(e.toString());
      return compileErrorExitCode;
    }
  }
}

class CompileCommand extends DartdevCommand {
  CompileCommand() : super('compile', 'Compile Dart to various formats.') {
    addSubcommand(CompileJSCommand());
    addSubcommand(CompileSnapshotCommand(
      commandName: 'jit-snapshot',
      help: 'to a JIT snapshot.',
      fileExt: 'jit',
      formatName: 'app-jit',
    ));
    addSubcommand(CompileSnapshotCommand(
      commandName: 'kernel',
      help: 'to a kernel snapshot.',
      fileExt: 'dill',
      formatName: 'kernel',
    ));
    addSubcommand(CompileNativeCommand(
      commandName: 'exe',
      help: 'to a self-contained executable.',
      format: 'exe',
    ));
    addSubcommand(CompileNativeCommand(
      commandName: 'aot-snapshot',
      help: 'to an AOT snapshot.',
      format: 'aot',
    ));
  }
}
