#!/usr/bin/env dart
import 'dart:async';
import 'dart:io';

import 'package:args/args.dart';
import 'package:front_end/src/api_prototype/compilation_message.dart';
import 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/api_prototype/summary_generator.dart';
import 'package:path/path.dart' as p;

import 'package:dev_compiler/src/analyzer/command.dart' as analyzer;
import 'package:dev_compiler/src/kernel/target.dart';

final String scriptDirectory = p.dirname(p.fromUri(Platform.script));

final String repoDirectory = p.normalize(p.join(scriptDirectory, "../../../"));

/// Path to the SDK analyzer summary file, "ddc_sdk.sum".
String analyzerSummary;

/// Path to the SDK kernel summary file, "ddc_sdk.dill".
String kernelSummary;

/// The directory that output is written to.
///
/// The DDC kernel SDK should be directly in this directory. The resulting
/// packages will be placed in a "pkg" subdirectory of this.
String outputDirectory;

String get pkgDirectory => p.join(outputDirectory, "pkg");

/// Compiles the packages that the DDC tests use to JS into the given output
/// directory.
///
/// If "--travis" is passed, builds the all of the modules tested on Travis.
/// Otherwise, only builds the modules needed by the tests.
///
/// If "--analyzer-sdk" is provided, uses that summary file and compiles the
/// packages to JS and analyzer summaries against that SDK summary. Otherwise,
/// it skips generating analyzer summaries and compiling to JS.
///
/// If "--kernel-sdk" is provided, uses that summary file and generates kernel
/// summaries for the test packages against that SDK summary. Otherwise, skips
/// generating kernel summaries.
Future main(List<String> arguments) async {
  var argParser = new ArgParser();
  argParser.addOption("analyzer-sdk",
      help: "Path to SDK analyzer summary '.sum' file");
  argParser.addOption("kernel-sdk",
      help: "Path to SDK Kernel summary '.dill' file");
  argParser.addOption("output",
      abbr: "o", help: "Directory to write output to.");
  argParser.addFlag("travis",
      help: "Build the additional packages tested on Travis.");

  ArgResults argResults;
  try {
    argResults = argParser.parse(arguments);
  } on ArgParserException catch (ex) {
    _usageError(argParser, ex.message);
  }

  if (argResults.rest.isNotEmpty) {
    _usageError(
        argParser, 'Unexpected arguments "${argResults.rest.join(' ')}".');
  }

  var isTravis = argResults["travis"] as bool;
  analyzerSummary = argResults["analyzer-sdk"] as String;
  kernelSummary = argResults["kernel-sdk"] as String;
  outputDirectory = argResults["output"] as String;

  new Directory(pkgDirectory).createSync(recursive: true);

  // Build leaf packages. These have no other package dependencies.

  // Under pkg.
  await compileModule('async_helper');
  await compileModule('expect', libs: ['minitest']);
  await compileModule('js', libs: ['js_util']);
  await compileModule('meta');
  if (isTravis) {
    await compileModule('microlytics', libs: ['html_channels']);
  }

  // Under third_party/pkg.
  await compileModule('collection');
  await compileModule('path');
  if (isTravis) {
    await compileModule('args', libs: ['command_runner']);
    await compileModule('charcode');
    await compileModule('fixnum');
    await compileModule('logging');
    await compileModule('markdown');
    await compileModule('mime');
    await compileModule('plugin', libs: ['manager']);
    await compileModule('typed_data');
    await compileModule('usage');
    await compileModule('utf');
  }

  // Composite packages with dependencies.
  await compileModule('stack_trace', deps: ['path']);
  await compileModule('matcher', deps: ['stack_trace']);
  if (isTravis) {
    await compileModule('async', deps: ['collection']);
  }

  if (!isTravis) {
    await compileModule('unittest', deps: [
      'matcher',
      'path',
      'stack_trace'
    ], libs: [
      'html_config',
      'html_individual_config',
      'html_enhanced_config'
    ]);
  }
}

void _usageError(ArgParser parser, [String message]) {
  if (message != null) {
    stderr.writeln(message);
    stderr.writeln();
  }

  stderr.writeln("Usage: dart build_pkgs.dart ...");
  stderr.writeln();
  stderr.writeln(parser.usage);
  exit(1);
}

/// Compiles a [module] with a single matching ".dart" library and additional
/// [libs] and [deps] on other modules.
Future compileModule(String module,
    {List<String> libs, List<String> deps}) async {
  if (analyzerSummary != null) compileModuleUsingAnalyzer(module, libs, deps);
  if (kernelSummary != null) await compileKernelSummary(module, libs, deps);
}

void compileModuleUsingAnalyzer(
    String module, List<String> libraries, List<String> dependencies) {
  var args = [
    '--dart-sdk-summary=$analyzerSummary',
    '-o${pkgDirectory}/$module.js'
  ];

  // There is always a library that matches the module.
  args.add('package:$module/$module.dart');

  // Add any additional libraries.
  if (libraries != null) {
    for (var lib in libraries) {
      args.add('package:$module/$lib.dart');
    }
  }

  // Add summaries for any modules this depends on.
  if (dependencies != null) {
    for (var dep in dependencies) {
      args.add('-s${pkgDirectory}/$dep.sum');
    }
  }

  // TODO(rnystrom): Hack. DDC has its own forked copy of async_helper that
  // has a couple of differences from pkg/async_helper. We should unfork them,
  // but I'm not sure how they'll affect the other non-DDC tests. For now, just
  // use ours.
  if (module == 'async_helper') {
    args.add('--url-mapping=package:async_helper/async_helper.dart,' +
        p.join(scriptDirectory, "../test/codegen/async_helper.dart"));
  }

  var exitCode = analyzer.compile(args);
  if (exitCode != 0) exit(exitCode);
}

Future compileKernelSummary(
    String module, List<String> libraries, List<String> dependencies) async {
  var succeeded = true;

  void errorHandler(CompilationMessage error) {
    if (error.severity == Severity.error) succeeded = false;
  }

  var options = new CompilerOptions()
    ..sdkSummary = p.toUri(kernelSummary)
    ..packagesFileUri = _uriInRepo(".packages")
    ..strongMode = true
    ..debugDump = true
    ..chaseDependencies = true
    ..onError = errorHandler
    ..reportMessages = true
    ..target = new DevCompilerTarget();

  var inputs = <Uri>[];

  if (module == "async_helper") {
    // TODO(rnystrom): Hack. DDC has its own forked copy of async_helper that
    // has a couple of differences from pkg/async_helper. We should unfork them,
    // but I'm not sure how they'll affect the other non-DDC tests. For now,
    // just use ours.
    inputs.add(_uriInRepo("pkg/dev_compiler/test/codegen/async_helper.dart"));
  } else {
    // There is always a library that matches the module.
    inputs.add(Uri.parse("package:$module/$module.dart"));

    // Add any other libraries too.
    if (libraries != null) {
      for (var lib in libraries) {
        inputs.add(Uri.parse("package:$module/$lib.dart"));
      }
    }
  }

  // Add summaries for any modules this depends on.
  if (dependencies != null) {
    var uris = <Uri>[];

    for (var dep in dependencies) {
      uris.add(p.toUri(p.absolute(p.join(pkgDirectory, "$dep.dill"))));
    }

    options.inputSummaries = uris;
  }

  // Compile the summary.
  var bytes = await summaryFor(inputs, options);
  var dillFile = new File(p.join(pkgDirectory, "$module.dill"));
  if (succeeded) {
    dillFile.writeAsBytesSync(bytes);
  } else {
    // Don't leave the previous version of the file on failure.
    if (dillFile.existsSync()) dillFile.deleteSync();

    stderr.writeln("Could not generate kernel summary for $module.");
    exit(1);
  }
}

Uri _uriInRepo(String pathInRepo) {
  // Walk up to repo root.
  var result = p.join(scriptDirectory, "../../../");
  result = p.join(result, pathInRepo);
  return p.toUri(p.absolute(p.normalize(result)));
}
