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

import 'dart:async';
import 'dart:convert' show utf8;
import 'dart:isolate' show RawReceivePort, ReceivePort, SendPort;

import "../bin/kernel_service.dart" as kernel_service;

import 'package:front_end/src/api_unstable/vm.dart' show Verbosity;

final bool verbose = new bool.fromEnvironment('TEST_VERBOSE');

Future<void> main() async {
  kernel_service.Status result;

  // Expect to work with both absolute and relative package specification
  // if the file specified exists and is valid.
  result = await singleShotCompile(
    relativeEntry,
    fooSourceFiles,
    absolutePackageConfig,
  );
  expect(result, kernel_service.Status.ok);
  result = await singleShotCompile(
    relativeEntry,
    fooSourceFiles,
    relativePackageConfig,
  );
  expect(result, kernel_service.Status.ok);

  // Expect an error with both absolute and relative package specification
  // if the file specified does not exist.
  result = await singleShotCompile(
    relativeEntry,
    fooSourceFiles,
    nonExistentAbsolutePackageConfig,
  );
  expect(result, kernel_service.Status.error);
  result = await singleShotCompile(
    relativeEntry,
    fooSourceFiles,
    nonExistentRelativePackageConfig,
  );
  expect(result, kernel_service.Status.error);

  // Expect an error with both absolute and relative package specification
  // if the file specified does exist but is invalid.
  result = await singleShotCompile(
    relativeEntry,
    fooSourceFiles,
    invalidAbsolutePackageConfig,
  );
  expect(result, kernel_service.Status.error);
  result = await singleShotCompile(
    relativeEntry,
    fooSourceFiles,
    invalidRelativePackageConfig,
  );
  expect(result, kernel_service.Status.error);
}

void expect(kernel_service.Status actual, kernel_service.Status expected) {
  if (actual != expected) {
    throw "Got $actual but expected $expected";
  }
}

String relativeEntry = "entry.dart";

String relativePackageConfig = "packageConfig.json";
String absolutePackageConfig = Uri.base.resolve(relativePackageConfig).path;

String nonExistentRelativePackageConfig = "nonexisting.json";
String nonExistentAbsolutePackageConfig =
    Uri.base.resolve(nonExistentRelativePackageConfig).path;

String invalidRelativePackageConfig = "invalidPackageConfig.json";
String invalidAbsolutePackageConfig =
    Uri.base.resolve(invalidRelativePackageConfig).path;

List fooSourceFiles = [
  Uri.base.resolve(relativeEntry).path,
  utf8.encode("""
        import "package:foo/bar.dart";
        main() {
          bar();
        }
      """),
  Uri.base.resolve("foo/lib/bar.dart").path,
  utf8.encode("""
        bar() {
          print("Hello from bar!");
        }
      """),
  absolutePackageConfig,
  utf8.encode("""
        {
          "configVersion": 2,
          "packages": [
            {
              "name": "foo",
              "rootUri": "foo/",
              "packageUri": "lib/"
            }
          ]
        }
      """),
  invalidAbsolutePackageConfig,
  utf8.encode(/* missing comma after rootUri line*/ """
        {
          "configVersion": 2,
          "packages": [
            {
              "name": "foo",
              "rootUri": "foo/"
              "packageUri": "lib/"
            }
          ]
        }
      """),
];

Future<kernel_service.Status> singleShotCompile(
  String entryFile,
  List sourceFiles,
  String? packageConfig,
) async {
  final RawReceivePort kernelServicePort = kernel_service.main();
  final SendPort sendPort = kernelServicePort.sendPort;
  final ReceivePort myReceivePort = new ReceivePort();

  sendPort.send([
    /* [0] = int = tag = */ kernel_service.kCompileTag,
    /* [1] = SendPort = sendport = */ myReceivePort.sendPort,
    /* [2] = String? = inputFileUri = */ entryFile,
    /* [3] = various = platformKernel = */ null,
    /* [4] = bool = incremental = */ false,
    /* [5] = bool = for_snapshot = */ false,
    /* [6] = bool = embed_sources = */ true,
    /* [8] = int = isolateGroupId = */ 42,
    /* [9] = List = sourceFiles = */ sourceFiles,
    /* [10] = bool = enableAsserts = */ true,
    /* [11] = List<String>? = experimentalFlags = */ [],
    /* [12] = String? = packageConfig = */ packageConfig,
    /* [13] = String? = multirootFilepaths = */ null,
    /* [14] = String? = multirootScheme = */ null,
    /* [16] = String = verbosityLevel = */ Verbosity.all.name,
    /* [17] = bool = enableMirrors = */ false,
  ]);

  // Wait for kernel-service response.
  final StreamIterator streamIterator = new StreamIterator(myReceivePort);
  await streamIterator.moveNext();

  // Close ports so we can return below.
  kernelServicePort.close();
  myReceivePort.close();

  // Examine kernel-service response.
  final List m = streamIterator.current as List;
  final int status = m.first;
  if (status == kernel_service.Status.ok.index) {
    expectLength(m, 2);
    final List<int> bytes = m[1];
    if (verbose) {
      print("OK --- ${bytes.length} bytes dill");
    }
    return kernel_service.Status.ok;
  } else if (status == kernel_service.Status.error.index) {
    expectLength(m, 3);
    final String errors = m[1];
    final List<int> bytes = m[2];
    if (verbose) {
      print("Compiled with errors --- $errors and ${bytes.length} bytes dill");
    }
    return kernel_service.Status.error;
  } else if (status == kernel_service.Status.crash.index) {
    expectLength(m, 2);
    final String errors = m[1];
    if (verbose) {
      print("Compiler crashed --- $errors");
    }
    return kernel_service.Status.crash;
  } else {
    throw "Unknow status: $m";
  }
}

void expectLength(List list, int expectedLength) {
  if (list.length != expectedLength) {
    throw "Expected $expectedLength entries, got ${list.length}: $list";
  }
}
