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

import 'dart:io' hide Link;
import 'dart:isolate';

import 'package:async_helper/async_helper.dart';
import 'package:compiler/src/compiler.dart';
import 'package:expect/expect.dart';
import 'package:kernel/ast.dart' as ir;

import '../equivalence/id_equivalence_helper.dart';
import '../deferred_loading/deferred_loading_test_helper.dart';

///  Add in options to pass to the compiler like
/// `Flags.disableTypeInference` or `Flags.disableInlining`
const List<String> compilerOptions = const [];

const List<String> tests = [
  'diamond',
  'diamond_and',
  'diamond_fuse',
  'diamond_or',
  'two_step',
  'two_branch',
];

Map<String, List<String>> createPerTestOptions() {
  Map<String, List<String>> perTestOptions = {};
  for (var test in tests) {
    Uri constraints = Platform.script.resolve('data/$test/constraints.json');
    perTestOptions['$test'] = ['--read-program-split=$constraints'];
  }
  return perTestOptions;
}

/// Returns a list of the deferred imports in a component where each import
/// becomes a string of 'uri#prefix'.
List<String> getDeferredImports(ir.Component component) {
  List<String> imports = [];
  for (var library in component.libraries) {
    for (var import in library.dependencies) {
      if (import.isDeferred) {
        imports.add('${library.importUri}#${import.name}');
      }
    }
  }
  imports.sort();
  return imports;
}

/// A helper function which performs the following steps:
/// 1) Get deferred imports from a given [component]
/// 2) Spawns the supplied [constraintsUri] in its own isolate
/// 3) Passes deferred imports via a port to the spawned isolate
/// 4) Listens for a json string from the spawned isolated and returns the
///    results as a a [Future<String>].
Future<String> constraintsToJson(
    ir.Component component, Uri constraintsUri) async {
  var imports = getDeferredImports(component);
  SendPort sendPort;
  var receivePort = ReceivePort();
  var isolate = await Isolate.spawnUri(constraintsUri, [], receivePort.sendPort,
      paused: true);
  isolate.addOnExitListener(receivePort.sendPort);
  isolate.resume(isolate.pauseCapability);
  String json;
  await for (var msg in receivePort) {
    if (msg == null) {
      receivePort.close();
    } else if (sendPort == null) {
      sendPort = msg;
      sendPort.send(imports);
    } else if (json == null) {
      json = msg;
    } else {
      throw 'Unexpected message $msg';
    }
  }
  return json;
}

Uri getFileInTestFolder(String test, String file) =>
    Platform.script.resolve('data/$test/$file');

Future<String> compileConstraintsToJson(String test, Compiler compiler) async {
  var constraints = getFileInTestFolder(test, 'constraints.dart');
  var component = compiler.componentForTesting;
  return constraintsToJson(component, constraints);
}

File getConstraintsJsonFile(String test) {
  var constraintsJsonUri = getFileInTestFolder(test, 'constraints.json');
  return File(constraintsJsonUri.toFilePath());
}

/// Verifies the programmatic API produces the expected JSON.
Future<void> verifyCompiler(String test, Compiler compiler) async {
  var json = await compileConstraintsToJson(test, compiler);
  Expect.equals(getConstraintsJsonFile(test).readAsStringSync(), json);
}

/// Generates constraint JSON.
Future<void> generateJSON(String test, Compiler compiler) async {
  var json = await compileConstraintsToJson(test, compiler);
  getConstraintsJsonFile(test).writeAsStringSync(json);
}

/// Compute the [OutputUnit]s for all source files involved in the test, and
/// ensure that the compiler is correctly calculating what is used and what is
/// not. We expect all test entry points to be in the `data` directory and any
/// or all supporting libraries to be in the `libs` folder, starting with the
/// same name as the original file in `data`.
main(List<String> args) {
  bool generateGoldens = args.contains('-g');
  asyncTest(() async {
    Directory dataDir = Directory.fromUri(Platform.script.resolve('data'));
    await checkTests(dataDir, const OutputUnitDataComputer(),
        options: compilerOptions,
        perTestOptions: createPerTestOptions(),
        args: args, setUpFunction: () {
      importPrefixes.clear();
    },
        testedConfigs: allSpecConfigs,
        verifyCompiler: generateGoldens ? generateJSON : verifyCompiler);
  });
}
