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

// @dart = 2.9

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

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,
    {String fileName: 'main.dart',
    List<String> additionalDills: const [],
    CompilerOptions options,
    bool retainDataForTesting: false,
    bool requireMain: true}) 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, additionalDills: additionalDills);
  return await kernelForProgramInternal(toTestUri(fileName), options,
      retainDataForTesting: retainDataForTesting, requireMain: requireMain);
}

/// 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> additionalDills: const [], CompilerOptions options}) async {
  options ??= new CompilerOptions();
  await setup(options, sources, additionalDills: additionalDills);
  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> additionalDills: const [],
    CompilerOptions options,
    bool truncate: false}) async {
  options ??= new CompilerOptions();
  await setup(options, sources, additionalDills: additionalDills);
  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> additionalDills: 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)
    ..additionalDills = additionalDills.map(toTestUri).toList();
  if (options.packagesFileUri == null) {
    options.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));
}
