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

// @dart = 2.7

library dart2js.test.memory_compiler;

import 'dart:async';

import 'package:_fe_analyzer_shared/src/util/filenames.dart';
import 'package:compiler/compiler.dart' show DiagnosticHandler;
import 'package:compiler/compiler_new.dart'
    show CompilationResult, CompilerDiagnostics, CompilerOutput, Diagnostic;
import 'package:compiler/src/common.dart';
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;

import 'package:front_end/src/api_unstable/dart2js.dart' as fe;

import 'memory_source_file_helper.dart';

export 'output_collector.dart';
export 'package:compiler/compiler_new.dart' show CompilationResult;
export 'diagnostic_helper.dart';

bool isDart2jsNnbd =
    Platform.environment['DART_CONFIGURATION'] == 'ReleaseX64NNBD';

String sdkPath = isDart2jsNnbd ? 'sdk_nnbd/lib' : 'sdk/lib';

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

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

Uri sdkPlatformBinariesUri =
    Uri.parse(nativeToUriPath(Platform.resolvedExecutable)).resolve('.');

String sdkPlatformBinariesPath = sdkPlatformBinariesUri.toString();

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

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

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

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

// 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<CompilationResult> runCompiler(
    {Map<String, dynamic> memorySourceFiles: const <String, dynamic>{},
    Uri entryPoint,
    CompilerDiagnostics diagnosticHandler,
    CompilerOutput outputProvider,
    List<String> options: const <String>[],
    bool showDiagnostics: true,
    Uri librariesSpecificationUri,
    Uri packageConfig,
    void beforeRun(CompilerImpl compiler)}) async {
  if (entryPoint == null) {
    entryPoint = Uri.parse('memory:main.dart');
  }
  CompilerImpl compiler = compilerFor(
      entryPoint: entryPoint,
      memorySourceFiles: memorySourceFiles,
      diagnosticHandler: diagnosticHandler,
      outputProvider: outputProvider,
      options: options,
      showDiagnostics: showDiagnostics,
      librariesSpecificationUri: librariesSpecificationUri,
      packageConfig: packageConfig);
  if (beforeRun != null) {
    beforeRun(compiler);
  }
  bool isSuccess = await compiler.run(entryPoint);
  fe.InitializedCompilerState compilerState = kernelInitializedCompilerState =
      compiler.kernelLoader.initializedCompilerState;
  return new CompilationResult(compiler,
      isSuccess: isSuccess, kernelInitializedCompilerState: compilerState);
}

CompilerImpl compilerFor(
    {Uri entryPoint,
    Map<String, dynamic> memorySourceFiles: const <String, dynamic>{},
    CompilerDiagnostics diagnosticHandler,
    CompilerOutput outputProvider,
    List<String> options: const <String>[],
    bool showDiagnostics: true,
    Uri librariesSpecificationUri,
    Uri packageConfig}) {
  retainDataForTesting = true;
  librariesSpecificationUri ??= sdkLibrariesSpecificationUri;

  if (packageConfig == null) {
    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 .packages file there.
      packageConfig = Uri.base.resolve('.packages');
    }
  }

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

  if (outputProvider == null) {
    outputProvider = const NullCompilerOutput();
  }

  CompilerOptions compilerOptions = CompilerOptions.parse(options,
      librariesSpecificationUri: librariesSpecificationUri)
    ..entryPoint = entryPoint
    ..environment = {}
    ..packageConfig = packageConfig;
  compilerOptions.kernelInitializedCompilerState =
      kernelInitializedCompilerState;
  CompilerImpl compiler = new CompilerImpl(
      provider, outputProvider, diagnosticHandler, compilerOptions);

  return compiler;
}

DiagnosticHandler createDiagnosticHandler(DiagnosticHandler diagnosticHandler,
    SourceFileProvider provider, bool showDiagnostics) {
  var handler = diagnosticHandler;
  if (showDiagnostics) {
    if (diagnosticHandler == null) {
      handler = new FormattingDiagnosticHandler(provider);
    } else {
      var formattingHandler = new FormattingDiagnosticHandler(provider);
      handler = (Uri uri, int begin, int end, String message, Diagnostic kind) {
        diagnosticHandler(uri, begin, end, message, kind);
        formattingHandler(uri, begin, end, message, kind);
      };
    }
  } else if (diagnosticHandler == null) {
    handler = (Uri uri, int begin, int end, String message, Diagnostic kind) {};
  }
  return handler;
}

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