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

// Partial test that the closed world computed from [WorldImpact]s derived from
// kernel is equivalent to the original computed from resolution.
library dart2js.kernel.compiler_helper;

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

import 'package:compiler/src/commandline_options.dart' show Flags;
import 'package:compiler/src/common.dart';
import 'package:compiler/src/dart2js.dart' as dart2js;
import 'package:_fe_analyzer_shared/src/util/filenames.dart';
import 'package:expect/expect.dart';
import 'package:sourcemap_testing/src/stacktrace_helper.dart';
import 'package:compiler/src/util/memory_compiler.dart';

Future createTemp(Uri entryPoint, Map<String, String> memorySourceFiles,
    {bool printSteps = false}) async {
  if (memorySourceFiles.isNotEmpty) {
    Directory dir = await Directory.systemTemp.createTemp('dart2js-with-dill');
    if (printSteps) {
      print('--- create temp directory $dir -------------------------------');
    }
    memorySourceFiles.forEach((String name, String source) {
      File.fromUri(dir.uri.resolve(name)).writeAsStringSync(source);
    });
    entryPoint = dir.uri.resolve(entryPoint.path);
  }
  return entryPoint;
}

Future<D8Result> runWithD8(
    {Uri? entryPoint,
    Map<String, String> memorySourceFiles = const <String, String>{},
    List<String> options = const <String>[],
    String? expectedOutput,
    bool printJs = false,
    bool printSteps = false}) async {
  retainDataForTesting = true;
  entryPoint ??= Uri.parse('memory:main.dart');
  Uri mainFile =
      await createTemp(entryPoint, memorySourceFiles, printSteps: printSteps);
  Uri output = nativeToUri(mainFile.resolve('out.js').path);

  CompilationResult compilationResult = await getCompilationResultsForD8(
      mainFile, output,
      options: options, printJs: printJs, printSteps: printSteps);
  final d8Result = executeJsWithD8([output],
      expectedOutput: expectedOutput, printSteps: printSteps);
  return D8Result(compilationResult, d8Result, output.toFilePath());
}

Future<CompilationResult> getCompilationResultsForD8(
    Uri mainFile, Uri outputFile,
    {List<String> options = const <String>[],
    bool printJs = false,
    bool printSteps = false}) async {
  List<String> dart2jsArgs = [
    mainFile.toString(),
    '-o${outputFile.toFilePath()}',
    if (Platform.packageConfig != null) '--packages=${Platform.packageConfig}',
    ...options,
    if (options.contains(Flags.noSoundNullSafety))
      // Unsound platform dill files are no longer packaged in the SDK and must
      // be read from the build directory during tests.
      '--platform-binaries=$buildPlatformBinariesPath',
  ];
  if (printSteps) print('Running: dart2js ${dart2jsArgs.join(' ')}');

  CompilationResult result = await dart2js.internalMain(dart2jsArgs);
  Expect.isTrue(result.isSuccess);
  if (printJs) {
    print('dart2js output:');
    print(new File(outputFile.toFilePath()).readAsStringSync());
  }
  return result;
}

ProcessResult executeJsWithD8(List<Uri> jsFiles,
    {String? expectedOutput, bool printSteps = false}) {
  List<String> d8Args = [
    '$sdkPath/_internal/js_runtime/lib/preambles/d8.js',
    ...jsFiles.map((u) => u.toFilePath())
  ];
  if (printSteps) print('Running: d8 ${d8Args.join(' ')}');
  ProcessResult runResult = Process.runSync(d8executable, d8Args);
  String out = '${runResult.stderr}\n${runResult.stdout}';
  if (printSteps) print('d8 output:');
  if (printSteps) print(out);
  if (expectedOutput != null) {
    Expect.equals(0, runResult.exitCode, "Unexpected exit code.");
    Expect.stringEquals(expectedOutput.trim(),
        runResult.stdout.replaceAll('\r\n', '\n').trim());
  }
  return runResult;
}

class D8Result {
  final CompilationResult compilationResult;
  final ProcessResult runResult;
  final String outputPath;

  D8Result(this.compilationResult, this.runResult, this.outputPath);
}
