// 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/compiler_new.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/common.dart';
import 'package:compiler/src/common/names.dart';
import 'package:compiler/src/common/tasks.dart';
import 'package:compiler/src/compiler.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/kernel/element_map_impl.dart';
import 'package:compiler/src/kernel/kernel_strategy.dart';
import 'package:compiler/src/library_loader.dart';
import 'package:compiler/src/universe/world_builder.dart';
import 'package:compiler/src/util/util.dart';
import 'package:expect/expect.dart';
import 'package:kernel/ast.dart' as ir;
import '../memory_compiler.dart';
import '../../../../pkg/compiler/tool/generate_kernel.dart' as generate;

typedef Future<Compiler> CompileFunction();

/// Create multiple compilations for a list of [sources].
///
/// This methods speeds up testing kernel based compilation by creating the IR
/// nodes for all [sources] at the same time. The returned list of
/// [CompileFunction]s compiles one of the [source] at a time using the kernel
/// based compiler.
///
/// Currently, the returned compile function only runs with '--analyze-only'
/// flag.
Future<List<CompileFunction>> compileMultiple(List<String> sources) async {
  List<Uri> uris = <Uri>[];
  Uri entryPoint = Uri.parse('memory:main.dart');
  Map<String, String> memorySourceFiles = <String, String>{
    'main.dart': 'main() {}'
  };
  for (String source in sources) {
    String name = 'input${memorySourceFiles.length}.dart';
    Uri uri = Uri.parse('memory:$name');
    memorySourceFiles[name] = source;
    uris.add(uri);
  }
  Compiler compiler = compilerFor(
      entryPoint: entryPoint,
      memorySourceFiles: memorySourceFiles,
      options: [Flags.analyzeAll, Flags.useKernel, Flags.enableAssertMessage]);
  compiler.librariesToAnalyzeWhenRun = uris;
  await compiler.run(entryPoint);

  List<CompileFunction> compilers = <CompileFunction>[];
  for (Uri uri in uris) {
    compilers.add(() async {
      Compiler compiler2 = compilerFor(
          entryPoint: uri,
          memorySourceFiles: memorySourceFiles,
          options: [
            Flags.analyzeOnly,
            Flags.enableAssertMessage,
            Flags.loadFromDill
          ]);
      ElementResolutionWorldBuilder.useInstantiationMap = true;
      compiler2.resolution.retainCachesForTesting = true;
      KernelFrontEndStrategy frontendStrategy = compiler2.frontendStrategy;
      KernelToElementMapImpl elementMap = frontendStrategy.elementMap;
      ir.Program program = new ir.Program(
          libraries:
              compiler.backend.kernelTask.kernel.libraryDependencies(uri));
      LibraryElement library = compiler.libraryLoader.lookupLibrary(uri);
      Expect.isNotNull(library, 'No library found for $uri');
      program.mainMethod = compiler.backend.kernelTask.kernel
          .functionToIr(library.findExported(Identifiers.main));
      compiler2.libraryLoader = new MemoryDillLibraryLoaderTask(
          elementMap, compiler2.reporter, compiler2.measurer, program);
      await compiler2.run(uri);
      return compiler2;
    });
  }
  return compilers;
}

/// Analyze [memorySourceFiles] with [entryPoint] as entry-point using the
/// kernel based element model. The returned [Pair] contains the compiler used
/// to create the IR and the kernel based compiler.
Future<Pair<Compiler, Compiler>> analyzeOnly(
    Uri entryPoint, Map<String, String> memorySourceFiles,
    {bool printSteps: false}) async {
  if (printSteps) {
    print('---- analyze-all -------------------------------------------------');
  }
  Compiler compiler = compilerFor(
      entryPoint: entryPoint,
      memorySourceFiles: memorySourceFiles,
      options: [Flags.analyzeAll, Flags.useKernel, Flags.enableAssertMessage]);
  await compiler.run(entryPoint);

  if (printSteps) {
    print('---- closed world from kernel ------------------------------------');
  }
  Compiler compiler2 = compilerFor(
      entryPoint: entryPoint,
      memorySourceFiles: memorySourceFiles,
      options: [
        Flags.analyzeOnly,
        Flags.enableAssertMessage,
        Flags.loadFromDill
      ]);
  ElementResolutionWorldBuilder.useInstantiationMap = true;
  compiler2.resolution.retainCachesForTesting = true;
  KernelFrontEndStrategy frontendStrategy = compiler2.frontendStrategy;
  KernelToElementMapImpl elementMap = frontendStrategy.elementMap;
  compiler2.libraryLoader = new MemoryDillLibraryLoaderTask(
      elementMap,
      compiler2.reporter,
      compiler2.measurer,
      compiler.backend.kernelTask.program);
  await compiler2.run(entryPoint);
  return new Pair<Compiler, Compiler>(compiler, compiler2);
}

class MemoryDillLibraryLoaderTask extends DillLibraryLoaderTask {
  final ir.Program program;

  MemoryDillLibraryLoaderTask(KernelToElementMapImpl elementMap,
      DiagnosticReporter reporter, Measurer measurer, this.program)
      : super(elementMap, null, null, reporter, measurer);

  Future<LoadedLibraries> loadLibrary(Uri resolvedUri,
      {bool skipFileWithPartOfTag: false}) async {
    return createLoadedLibraries(program);
  }
}

Future<Compiler> compileWithDill(
    Uri entryPoint, Map<String, String> memorySourceFiles, List<String> options,
    {bool printSteps: false,
    CompilerOutput compilerOutput,
    void beforeRun(Compiler compiler)}) 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) {
      new File.fromUri(dir.uri.resolve(name)).writeAsStringSync(source);
    });
    entryPoint = dir.uri.resolve(entryPoint.path);
  }
  if (printSteps) {
    print('---- generate dill -----------------------------------------------');
  }

  Uri dillFile = Uri.parse('$entryPoint.dill');
  String buildDir = Platform.isMacOS ? 'xcodebuild' : 'out';
  String configuration =
      Platform.environment['DART_CONFIGURATION'] ?? 'ReleaseX64';
  await generate.main([
    '--platform=$buildDir/$configuration/patched_dart2js_sdk/platform.dill',
    '$entryPoint'
  ]);

  if (printSteps) {
    print('---- compile from dill $dillFile ---------------------------------');
  }
  Compiler compiler = compilerFor(
      entryPoint: dillFile,
      options: [Flags.loadFromDill]..addAll(options),
      outputProvider: compilerOutput);
  ElementResolutionWorldBuilder.useInstantiationMap = true;
  compiler.resolution.retainCachesForTesting = true;
  if (beforeRun != null) {
    beforeRun(compiler);
  }
  await compiler.run(dillFile);
  return compiler;
}
