// Copyright (c) 2017, 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' show ArgParser, ArgResults;
import 'package:front_end/src/api_unstable/vm.dart';
import 'package:kernel/binary/ast_to_binary.dart';
import 'package:kernel/src/tool/batch_util.dart' as batch_util;
import 'package:kernel/target/targets.dart' show TargetFlags;
import 'package:kernel/text/ast_to_text.dart'
    show globalDebuggingNames, NameSystem;
import 'package:vm/kernel_front_end.dart'
    show compileToKernel, ErrorDetector, ErrorPrinter, parseCommandLineDefines;
import 'package:vm/target/vm.dart' show VmTarget;

final ArgParser _argParser = new ArgParser(allowTrailingOptions: true)
  ..addOption('platform',
      help: 'Path to vm_platform_strong.dill file', defaultsTo: null)
  ..addOption('packages', help: 'Path to .packages file', defaultsTo: null)
  ..addOption('output',
      abbr: 'o', help: 'Path to resulting dill file', defaultsTo: null)
  ..addFlag('aot',
      help:
          'Produce kernel file for AOT compilation (enables global transformations).',
      defaultsTo: false)
  ..addFlag('sync-async',
      help: 'Start `async` functions synchronously', defaultsTo: true)
  ..addFlag('embed-sources',
      help: 'Embed source files in the generated kernel component',
      defaultsTo: true)
  ..addFlag('tfa',
      help:
          'Enable global type flow analysis and related transformations in AOT mode.',
      defaultsTo: true)
  ..addMultiOption('define',
      abbr: 'D',
      help: 'The values for the environment constants (e.g. -Dkey=value).')
  ..addFlag('enable-asserts',
      help: 'Whether asserts will be enabled.', defaultsTo: false)
  ..addFlag('enable-constant-evaluation',
      help: 'Whether kernel constant evaluation will be enabled.',
      defaultsTo: true)
  ..addFlag('gen-bytecode', help: 'Generate bytecode', defaultsTo: false)
  ..addFlag('emit-bytecode-source-positions',
      help: 'Emit source positions in bytecode', defaultsTo: false)
  ..addFlag('drop-ast',
      help: 'Drop AST for members with bytecode', defaultsTo: false)
  ..addFlag('use-future-bytecode-format',
      help: 'Generate bytecode in the bleeding edge format', defaultsTo: false);

final String _usage = '''
Usage: dart pkg/vm/bin/gen_kernel.dart --platform vm_platform_strong.dill [options] input.dart
Compiles Dart sources to a kernel binary file for Dart VM.

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

const int _badUsageExitCode = 1;
const int _compileTimeErrorExitCode = 254;

main(List<String> arguments) async {
  if (arguments.isNotEmpty && arguments.last == '--batch') {
    await runBatchModeCompiler();
  } else {
    exit(await compile(arguments));
  }
}

Future<int> compile(List<String> arguments) async {
  final ArgResults options = _argParser.parse(arguments);
  final String platformKernel = options['platform'];

  if ((options.rest.length != 1) || (platformKernel == null)) {
    print(_usage);
    return _badUsageExitCode;
  }

  final String filename = options.rest.single;
  final String kernelBinaryFilename = options['output'] ?? "$filename.dill";
  final String packages = options['packages'];
  final bool aot = options['aot'];
  final bool tfa = options['tfa'];
  final bool genBytecode = options['gen-bytecode'];
  final bool emitBytecodeSourcePositions =
      options['emit-bytecode-source-positions'];
  final bool dropAST = options['drop-ast'];
  final bool useFutureBytecodeFormat = options['use-future-bytecode-format'];
  final bool enableAsserts = options['enable-asserts'];
  final bool enableConstantEvaluation = options['enable-constant-evaluation'];
  final Map<String, String> environmentDefines = {};

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

  final errorPrinter = new ErrorPrinter();
  final errorDetector = new ErrorDetector(previousErrorHandler: errorPrinter);

  final CompilerOptions compilerOptions = new CompilerOptions()
    ..target = new VmTarget(new TargetFlags(syncAsync: true))
    ..linkedDependencies = <Uri>[
      Uri.base.resolveUri(new Uri.file(platformKernel))
    ]
    ..packagesFileUri =
        packages != null ? Uri.base.resolveUri(new Uri.file(packages)) : null
    ..onDiagnostic = (DiagnosticMessage m) {
      errorDetector(m);
    }
    ..embedSourceText = options['embed-sources'];

  final inputUri = new Uri.file(filename);
  final component = await compileToKernel(
      Uri.base.resolveUri(inputUri), compilerOptions,
      aot: aot,
      useGlobalTypeFlowAnalysis: tfa,
      environmentDefines: environmentDefines,
      genBytecode: genBytecode,
      emitBytecodeSourcePositions: emitBytecodeSourcePositions,
      dropAST: dropAST,
      useFutureBytecodeFormat: useFutureBytecodeFormat,
      enableAsserts: enableAsserts,
      enableConstantEvaluation: enableConstantEvaluation);

  errorPrinter.printCompilationMessages(inputUri);

  if (errorDetector.hasCompilationErrors || (component == null)) {
    return _compileTimeErrorExitCode;
  }

  final IOSink sink = new File(kernelBinaryFilename).openWrite();
  final BinaryPrinter printer = new BinaryPrinter(sink);
  printer.writeComponentFile(component);
  await sink.close();

  return 0;
}

Future runBatchModeCompiler() async {
  await batch_util.runBatch((List<String> arguments) async {
    // TODO(kustermann): Once we know where the new IKG api is and how to use
    // it, we should take advantage of it.
    //
    // Important things to note:
    //
    //   * Our global transformations must never alter the AST structures which
    //     the statefull IKG generator keeps across compilations.
    //     => We need to make our own copy.
    //
    //   * We must ensure the stateful IKG generator keeps giving us all the
    //     compile-time errors, warnings, hints for every compilation and we
    //     report the compilation result accordingly.
    //
    final exitCode = await compile(arguments);

    // Re-create global NameSystem to avoid accumulating garbage.
    globalDebuggingNames = new NameSystem();

    switch (exitCode) {
      case 0:
        return batch_util.CompilerOutcome.Ok;
      case _compileTimeErrorExitCode:
      case _badUsageExitCode:
        return batch_util.CompilerOutcome.Fail;
      default:
        throw 'Could not obtain correct exit code from compiler.';
    }
  });
}
