#!/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';

/// 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
        ? new StdAsyncWorkerConnection()
        : new SendPortAsyncWorkerConnection(sendPort);
    await _CompilerWorker(parsedArgs, workerConnection).run();
  } else if (parsedArgs.isBatch) {
    await runBatch(parsedArgs);
  } 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);

  /// Performs each individual work request.
  Future<WorkResponse> performRequest(WorkRequest request) async {
    var args = _startupArgs.merge(request.arguments);
    var output = StringBuffer();
    var result = await runZoned(() => compile(args), zoneSpecification:
        ZoneSpecification(print: (self, parent, zone, message) {
      output.writeln(message.toString());
    }));
    return WorkResponse()
      ..exitCode = result.success ? 0 : 1
      ..output = output.toString();
  }
}

/// Runs dartdevk in 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');
}
