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

library;

import 'dart:async';

import 'package:compiler/compiler_api.dart'
    as api
    show CompilationResult, CompilerDiagnostics, CompilerOutput, Diagnostic;
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common.dart';
import 'package:compiler/src/compiler.dart' show Compiler;
import 'package:compiler/src/diagnostics/messages.dart' show Message;
import 'package:compiler/src/null_compiler_output.dart' show NullCompilerOutput;
import 'package:compiler/src/options.dart' show CompilerOptions;
// ignore: implementation_imports
import 'package:front_end/src/api_unstable/dart2js.dart' as fe;

import 'memory_source_file_helper.dart';

export 'package:compiler/compiler_api.dart' show CompilationResult;

export 'diagnostic_helper.dart';
export 'output_collector.dart';

String sdkPath = 'sdk/lib';

String sdkLibrariesSpecificationPath = '$sdkPath/libraries.json';

Uri sdkLibrariesSpecificationUri = Uri.base.resolve(
  sdkLibrariesSpecificationPath,
);

Uri sdkPlatformBinariesUri = fe
    .computePlatformBinariesLocation()
    .resolve("dart2js_platform.dill")
    .resolve('.');

String sdkPlatformBinariesPath = sdkPlatformBinariesUri.toString();

Uri buildPlatformBinariesUri = fe
    .computePlatformBinariesLocation(forceBuildDir: true)
    .resolve("dart2js_platform.dill")
    .resolve('.');

String buildPlatformBinariesPath = buildPlatformBinariesUri.toString();

class MultiDiagnostics implements api.CompilerDiagnostics {
  final List<api.CompilerDiagnostics> diagnosticsList;

  const MultiDiagnostics([this.diagnosticsList = const []]);

  @override
  void report(
    covariant Message? message,
    Uri? uri,
    int? begin,
    int? end,
    String text,
    api.Diagnostic kind,
  ) {
    for (api.CompilerDiagnostics diagnostics in diagnosticsList) {
      diagnostics.report(message, uri, begin, end, text, kind);
    }
  }
}

api.CompilerDiagnostics createCompilerDiagnostics(
  api.CompilerDiagnostics? diagnostics,
  SourceFileProvider provider, {
  bool showDiagnostics = true,
  bool verbose = false,
}) {
  if (showDiagnostics) {
    if (diagnostics == null) {
      diagnostics =
          FormattingDiagnosticHandler()
            ..verbose = verbose
            ..registerFileProvider(provider);
    } else {
      var formattingHandler =
          FormattingDiagnosticHandler()
            ..verbose = verbose
            ..registerFileProvider(provider);
      diagnostics = MultiDiagnostics([diagnostics, formattingHandler]);
    }
  } else {
    diagnostics ??= MultiDiagnostics();
  }
  return diagnostics;
}

// Cached kernel state.
fe.InitializedCompilerState? kernelInitializedCompilerState;

/// memorySourceFiles can contain a map of string filename to string file
/// contents or string file name to binary file contents (hence the `dynamic`
/// type for the second parameter).
Future<api.CompilationResult> runCompiler({
  Map<String, dynamic> memorySourceFiles = const <String, dynamic>{},
  Uri? entryPoint,
  api.CompilerDiagnostics? diagnosticHandler,
  api.CompilerOutput? outputProvider,
  List<String> options = const <String>[],
  Map<String, String>? environment,
  bool showDiagnostics = true,
  Uri? librariesSpecificationUri,
  Uri? platformBinaries,
  Uri? packageConfig,
  bool skipPackageConfig = false,
  void Function(Compiler compiler)? beforeRun,
}) async {
  entryPoint ??= Uri.parse('memory:main.dart');
  Compiler compiler = compilerFor(
    entryPoint: entryPoint,
    memorySourceFiles: memorySourceFiles,
    diagnosticHandler: diagnosticHandler,
    outputProvider: outputProvider,
    options: options,
    environment: environment,
    showDiagnostics: showDiagnostics,
    librariesSpecificationUri: librariesSpecificationUri,
    platformBinaries: platformBinaries,
    packageConfig: packageConfig,
    skipPackageConfig: skipPackageConfig,
  );
  if (beforeRun != null) {
    beforeRun(compiler);
  }
  bool isSuccess = await compiler.run();
  fe.InitializedCompilerState? compilerState =
      kernelInitializedCompilerState = compiler.initializedCompilerState;
  return api.CompilationResult(
    compiler,
    isSuccess: isSuccess,
    kernelInitializedCompilerState: compilerState,
  );
}

Compiler compilerFor({
  Uri? entryPoint,
  Map<String, dynamic> memorySourceFiles = const <String, dynamic>{},
  api.CompilerDiagnostics? diagnosticHandler,
  api.CompilerOutput? outputProvider,
  List<String> options = const <String>[],
  Map<String, String>? environment,
  bool showDiagnostics = true,
  Uri? librariesSpecificationUri,
  Uri? platformBinaries,
  Uri? packageConfig,
  bool skipPackageConfig = false,
}) {
  retainDataForTesting = true;
  librariesSpecificationUri ??= sdkLibrariesSpecificationUri;

  if (packageConfig == null && !skipPackageConfig) {
    if (Platform.packageConfig != null) {
      packageConfig = Uri.base.resolve(Platform.packageConfig!);
    } else {
      // The tests are run with the base directory as the SDK root
      // so just use the package config there.
      packageConfig = Uri.base.resolve('.dart_tool/package_config.json');
    }
  }

  // Create a local in case we end up cloning memorySourceFiles.
  Map<String, dynamic> sources = memorySourceFiles;

  MemorySourceFileProvider provider;
  provider = MemorySourceFileProvider(sources);
  diagnosticHandler = createCompilerDiagnostics(
    diagnosticHandler,
    provider,
    showDiagnostics: showDiagnostics,
    verbose: options.contains('-v') || options.contains('--verbose'),
  );

  outputProvider ??= const NullCompilerOutput();

  options = [...options, '${Flags.entryUri}=$entryPoint'];

  CompilerOptions compilerOptions =
      CompilerOptions.parse(
          options,
          librariesSpecificationUri: librariesSpecificationUri,
          platformBinaries: platformBinaries,
        )
        ..environment = environment ?? {}
        ..packageConfig = packageConfig;

  compilerOptions.setDefaultOutputUriForTesting();
  compilerOptions.kernelInitializedCompilerState =
      kernelInitializedCompilerState;
  var compiler = Compiler(
    provider,
    outputProvider,
    diagnosticHandler,
    compilerOptions,
  );

  return compiler;
}

void main() {
  runCompiler(memorySourceFiles: {'main.dart': 'main() {}'});
}
