// 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.

/// A tool that invokes the CFE to compute kernel summary files.
///
/// This script can be used as a command-line command or a persistent server.
/// The server is implemented using the bazel worker protocol, so it can be used
/// within bazel as is. Other tools (like pub-build and package-build) also
/// use this persistent worker via the same protocol.

import 'dart:async';
import 'dart:io';
import 'dart:isolate';

import 'package:bazel_worker/bazel_worker.dart';
import 'package:front_end/src/api_unstable/bazel_worker.dart' as fe;
import 'package:frontend_server/compute_kernel.dart';

/// [sendPort] may be passed in when started in an isolate. If provided, it is
/// used for bazel worker communication instead of stdin/stdout.
main(List<String> args, SendPort? sendPort) async {
  args = preprocessArgs(args);

  if (args.contains('--persistent_worker')) {
    if (args.length != 1) {
      throw new StateError(
          "unexpected args, expected only --persistent-worker but got: $args");
    }
    await new KernelWorker(sendPort: sendPort).run();
  } else {
    var result = await computeKernel(args);
    if (!result.succeeded) {
      exitCode = 15;
    }
  }
}

/// A bazel worker loop that can compute full or summary kernel files.
class KernelWorker extends AsyncWorkerLoop {
  fe.InitializedCompilerState? previousState;

  /// If [sendPort] is provided it is used for bazel worker communication
  /// instead of stdin/stdout.
  KernelWorker({SendPort? sendPort})
      : super(
            connection: sendPort == null
                ? null
                : SendPortAsyncWorkerConnection(sendPort));

  Future<WorkResponse> performRequest(WorkRequest request) async {
    var outputBuffer = new StringBuffer();
    var response = new WorkResponse()..exitCode = 0;
    try {
      fe.InitializedCompilerState? previousStateToPass;
      if (request.arguments.contains("--reuse-compiler-result")) {
        previousStateToPass = previousState;
      } else {
        previousState = null;
      }

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

      var result = await computeKernel(request.arguments,
          isWorker: true,
          outputBuffer: outputBuffer,
          inputDigests: inputDigests,
          previousState: previousStateToPass);
      previousState = result.previousState;
      if (!result.succeeded) {
        response.exitCode = 15;
      }
    } catch (e, s) {
      outputBuffer.writeln(e);
      outputBuffer.writeln(s);
      response.exitCode = 15;
    }
    response.output = outputBuffer.toString();
    return response;
  }
}
