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

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',
  'fuse_with_and',
  'fuse_with_or',
  'two_step',
  'two_branch',
  'just_fuse',
];

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 [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);
  });
}
