#!/usr/bin/env dart
// Copyright (c) 2016, 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.

/// Command line entry point for Dart Development Compiler (dartdevc), used to
/// compile a collection of dart libraries into a single JS module

import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:isolate';
import 'package:bazel_worker/bazel_worker.dart';
import 'package:dev_compiler/src/compiler/shared_command.dart';
import 'package:dev_compiler/src/kernel/expression_compiler_worker.dart';

/// The entry point for the Dart Dev Compiler.
///
/// [sendPort] may be passed in when started in an isolate. If provided, it is
/// used for bazel worker communication instead of stdin/stdout.
Future main(List<String> args, [SendPort sendPort]) async {
  // Always returns a new modifiable list.
  var parsedArgs = ParsedArguments.from(args);

  if (parsedArgs.isWorker) {
    var workerConnection = sendPort == null
        ? StdAsyncWorkerConnection()
        : SendPortAsyncWorkerConnection(sendPort);
    await _CompilerWorker(parsedArgs, workerConnection).run();
  } else if (parsedArgs.isBatch) {
    await runBatch(parsedArgs);
  } else if (parsedArgs.isExpressionCompiler) {
    ExpressionCompilerWorker worker;
    if (sendPort != null) {
      var receivePort = ReceivePort();
      sendPort.send(receivePort.sendPort);
      worker = await ExpressionCompilerWorker.createFromArgs(parsedArgs.rest,
          requestStream: receivePort.cast<Map<String, dynamic>>(),
          sendResponse: sendPort.send);
    } else {
      worker = await ExpressionCompilerWorker.createFromArgs(parsedArgs.rest);
    }
    await worker.start();
  } else {
    var result = await compile(parsedArgs);
    exitCode = result.exitCode;
  }
}

/// Runs the compiler worker loop.
class _CompilerWorker extends AsyncWorkerLoop {
  /// The original args supplied to the executable.
  final ParsedArguments _startupArgs;

  _CompilerWorker(this._startupArgs, AsyncWorkerConnection workerConnection)
      : super(connection: workerConnection);

  /// Keeps track of our last compilation result so it can potentially be
  /// re-used in a worker.
  CompilerResult lastResult;

  /// Performs each individual work request.
  @override
  Future<WorkResponse> performRequest(WorkRequest request) async {
    var args = _startupArgs.merge(request.arguments);
    var output = StringBuffer();
    var context = args.reuseResult ? lastResult : null;

    /// Build a map of uris to digests.
    final inputDigests = <Uri, List<int>>{};
    for (var input in request.inputs) {
      inputDigests[sourcePathToUri(input.path)] = input.digest;
    }

    lastResult = await runZoned(
        () =>
            compile(args, previousResult: context, inputDigests: inputDigests),
        zoneSpecification:
            ZoneSpecification(print: (self, parent, zone, message) {
      output.writeln(message.toString());
    }));
    return WorkResponse()
      ..exitCode = lastResult.success ? 0 : 1
      ..output = output.toString();
  }
}

/// Runs DDC in Kernel batch mode for test.dart.
Future runBatch(ParsedArguments batchArgs) async {
  var totalTests = 0;
  var failedTests = 0;
  var watch = Stopwatch()..start();

  print('>>> BATCH START');

  String line;
  CompilerResult result;

  while ((line = stdin.readLineSync(encoding: utf8))?.isNotEmpty == true) {
    totalTests++;
    var args = batchArgs.merge(line.split(RegExp(r'\s+')));

    String outcome;
    try {
      result = await compile(args, previousResult: result);
      outcome = result.success ? 'PASS' : (result.crashed ? 'CRASH' : 'FAIL');
    } catch (e, s) {
      outcome = 'CRASH';
      print('Unhandled exception:');
      print(e);
      print(s);
    }

    stderr.writeln('>>> EOF STDERR');
    print('>>> TEST $outcome ${watch.elapsedMilliseconds}ms');
  }

  var time = watch.elapsedMilliseconds;
  print('>>> BATCH END (${totalTests - failedTests})/$totalTests ${time}ms');
}
