// Copyright (c) 2021, 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.

// @dart = 2.9

/// 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 'src/compiler/shared_command.dart';
import 'src/kernel/command.dart';
import 'src/kernel/expression_compiler_worker.dart';

/// The internal 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 internalMain(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) {
    await ExpressionCompilerWorker.createAndStart(parsedArgs.rest,
        sendPort: sendPort);
  } 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,
            compilerState: context?.kernelState, 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, compilerState: result?.kernelState);
      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');
}
