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

/// Common compiler options and helper functions used for testing.
library front_end.testing.compiler_options_common;

import 'dart:async' show Future;

import 'package:kernel/ast.dart' show Library, Component;

import '../api_prototype/front_end.dart'
    show
        CompilerOptions,
        CompilerResult,
        kernelForModule,
        kernelForProgramInternal,
        summaryFor;

import '../api_prototype/memory_file_system.dart'
    show MemoryFileSystem, MemoryFileSystemEntity;

import '../compute_platform_binaries_location.dart'
    show computePlatformBinariesLocation;

import '../fasta/hybrid_file_system.dart' show HybridFileSystem;

/// Generate kernel for a script.
///
/// [scriptOrSources] can be a String, in which case it is the script to be
/// compiled, or a Map containing source files. In which case, this function
/// compiles the entry whose name is [fileName].
///
/// Wraps [kernelForProgram] with some default testing options (see [setup]).
Future<CompilerResult> compileScript(dynamic scriptOrSources,
    {fileName: 'main.dart',
    List<String> inputSummaries: const [],
    List<String> linkedDependencies: const [],
    CompilerOptions options,
    bool retainDataForTesting: false}) async {
  options ??= new CompilerOptions();
  Map<String, dynamic> sources;
  if (scriptOrSources is String) {
    sources = {fileName: scriptOrSources};
  } else {
    assert(scriptOrSources is Map);
    sources = scriptOrSources;
  }
  await setup(options, sources,
      inputSummaries: inputSummaries, linkedDependencies: linkedDependencies);
  return await kernelForProgramInternal(toTestUri(fileName), options,
      retainDataForTesting: retainDataForTesting);
}

/// Generate a component for a modular compilation unit.
///
/// Wraps [kernelForModule] with some default testing options (see [setup]).
Future<Component> compileUnit(List<String> inputs, Map<String, dynamic> sources,
    {List<String> inputSummaries: const [],
    List<String> linkedDependencies: const [],
    CompilerOptions options}) async {
  options ??= new CompilerOptions();
  await setup(options, sources,
      inputSummaries: inputSummaries, linkedDependencies: linkedDependencies);
  return (await kernelForModule(inputs.map(toTestUri).toList(), options))
      .component;
}

/// Generate a summary for a modular compilation unit.
///
/// Wraps [summaryFor] with some default testing options (see [setup]).
Future<List<int>> summarize(List<String> inputs, Map<String, dynamic> sources,
    {List<String> inputSummaries: const [],
    CompilerOptions options,
    bool truncate: false}) async {
  options ??= new CompilerOptions();
  await setup(options, sources, inputSummaries: inputSummaries);
  return await summaryFor(inputs.map(toTestUri).toList(), options,
      truncate: truncate);
}

/// Defines a default set of options for testing:
///
///   * create a hybrid file system that stores [sources] in memory but allows
///   access to the physical file system to load the SDK. [sources] can
///   contain either source files (value is [String]) or .dill files (value
///   is [List<int>]).
///
///   * define an empty .packages file (if one isn't defined in sources)
///
///   * specify the location of the sdk summaries.
Future<Null> setup(CompilerOptions options, Map<String, dynamic> sources,
    {List<String> inputSummaries: const [],
    List<String> linkedDependencies: const []}) async {
  MemoryFileSystem fs = new MemoryFileSystem(_defaultDir);
  sources.forEach((name, data) {
    MemoryFileSystemEntity entity = fs.entityForUri(toTestUri(name));
    if (data is String) {
      entity.writeAsStringSync(data);
    } else {
      entity.writeAsBytesSync(data);
    }
  });
  MemoryFileSystemEntity dotPackagesFile =
      fs.entityForUri(toTestUri('.packages'));
  if (!await dotPackagesFile.exists()) dotPackagesFile.writeAsStringSync('');
  fs
      .entityForUri(invalidCoreLibsSpecUri)
      .writeAsStringSync(_invalidLibrariesSpec);
  options
    ..verify = true
    ..fileSystem = new HybridFileSystem(fs)
    ..inputSummaries = inputSummaries.map(toTestUri).toList()
    ..linkedDependencies = linkedDependencies.map(toTestUri).toList()
    ..packagesFileUri = toTestUri('.packages');

  if (options.sdkSummary == null) {
    options.sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
  }
}

/// A fake absolute directory used as the root of a memory-file system in the
/// helpers above.
Uri _defaultDir = Uri.parse('org-dartlang-test:///a/b/c/');

/// Convert relative file paths into an absolute Uri as expected by the test
/// helpers above.
Uri toTestUri(String relativePath) => _defaultDir.resolve(relativePath);

/// Uri to a libraries specification file that purposely provides
/// invalid Uris to dart:core and dart:async. Used by tests that want to ensure
/// that the sdk libraries are not loaded from sources, but read from a .dill
/// file.
Uri invalidCoreLibsSpecUri = toTestUri('invalid_sdk_libraries.json');

String _invalidLibrariesSpec = '''
{
  "vm": {
    "libraries": {
      "core":  {"uri": "/non_existing_file/core.dart"},
      "async": {"uri": "/non_existing_file/async.dart"}
    }
  }
}
''';

bool isDartCoreLibrary(Library lib) => isDartCore(lib.importUri);
bool isDartCore(Uri uri) => uri.scheme == 'dart' && uri.path == 'core';

/// Find a library in [component] whose Uri ends with the given [suffix]
Library findLibrary(Component component, String suffix) {
  return component.libraries
      .firstWhere((lib) => lib.importUri.path.endsWith(suffix));
}
