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

/// Test the modular compilation pipeline of dart2js.
///
/// This is a shell that runs multiple tests, one per folder under `data/`.
import 'dart:io';

import 'package:args/args.dart';
import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:front_end/src/compute_platform_binaries_location.dart'
    show computePlatformBinariesLocation;
import 'package:modular_test/src/io_pipeline.dart';
import 'package:modular_test/src/loader.dart';
import 'package:modular_test/src/pipeline.dart';
import 'package:modular_test/src/suite.dart';

_Options _options;
main(List<String> args) {
  _options = _Options.parse(args);
  asyncTest(() async {
    var baseUri = Platform.script.resolve('data/');
    var baseDir = Directory.fromUri(baseUri);
    var pipeline = new IOPipeline([
      SourceToDillStep(),
      GlobalAnalysisStep(),
      Dart2jsBackendStep(),
      RunD8(),
    ], cacheSharedModules: true);
    await for (var entry in baseDir.list(recursive: false)) {
      if (entry is Directory) {
        await _runTest(pipeline, entry.uri, baseUri);
      }
    }

    await pipeline.cleanup();
  });
}

Future<void> _runTest(IOPipeline pipeline, Uri uri, Uri baseDir) async {
  var dirName = uri.path.substring(baseDir.path.length);
  if (_options.filter != null && !dirName.contains(_options.filter)) {
    if (_options.showSkipped) print("skipped: $dirName");
    return;
  }

  print("testing: $dirName");
  ModularTest test = await loadTest(uri);
  if (_options.verbose) print(test.debugString());
  await pipeline.run(test);
}

const dillId = const DataId("dill");
const updatedDillId = const DataId("udill");
const globalDataId = const DataId("gdata");
const jsId = const DataId("js");
const txtId = const DataId("txt");

// Step that compiles sources in a module to a .dill file.
class SourceToDillStep implements IOModularStep {
  @override
  List<DataId> get resultData => const [dillId];

  @override
  bool get needsSources => true;

  @override
  List<DataId> get dependencyDataNeeded => const [dillId];

  @override
  List<DataId> get moduleDataNeeded => const [];

  @override
  bool get onlyOnMain => false;

  @override
  Future<void> execute(
      Module module, Uri root, ModuleDataToRelativeUri toUri) async {
    if (_options.verbose) print("step: source-to-dill on $module");
    // We use non file-URI schemes for representeing source locations in a
    // root-agnostic way. This allows us to refer to file across modules and
    // across steps without exposing the underlying temporary folders that are
    // created by the framework. In build systems like bazel this is especially
    // important because each step may be run on a different machine.
    //
    // Files in packages are defined in terms of `package:` URIs, while
    // non-package URIs are defined using the `dart-dev-app` scheme.
    String rootScheme = 'dev-dart-app';
    String sourceToImportUri(Uri relativeUri) {
      if (module.isPackage) {
        var basePath = module.packageBase.path;
        var packageRelativePath = basePath == "./"
            ? relativeUri.path
            : relativeUri.path.substring(basePath.length);
        return 'package:${module.name}/$packageRelativePath';
      } else {
        return '$rootScheme:/$relativeUri';
      }
    }

    // We create a .packages file which defines the location of this module if
    // it is a package.  The CFE requires that if a `package:` URI of a
    // dependency is used in an import, then we need that package entry in the
    // .packages file. However, after it checks that the definition exists, the
    // CFE will not actually use the resolved URI if a library for the import
    // URI is already found in one of the provided .dill files of the
    // dependencies. For that reason, and to ensure that a step only has access
    // to the files provided in a module, we generate a .packages with invalid
    // folders for other packages.
    // TODO(sigmund): follow up with the CFE to see if we can remove the need
    // for the .packages entry altogether if they won't need to read the
    // sources.
    var packagesContents = new StringBuffer();
    if (module.isPackage) {
      packagesContents.write('${module.name}:${module.packageBase}\n');
    }
    Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
    for (Module dependency in transitiveDependencies) {
      if (dependency.isPackage) {
        packagesContents.write('${dependency.name}:unused\n');
      }
    }

    await File.fromUri(root.resolve('.packages'))
        .writeAsString('$packagesContents');

    var sdkRoot = Platform.script.resolve("../../../../");
    var platform =
        computePlatformBinariesLocation().resolve("dart2js_platform.dill");

    List<String> workerArgs = [
      sdkRoot.resolve("utils/bazel/kernel_worker.dart").toFilePath(),
      '--no-summary-only',
      '--target',
      'dart2js',
      '--multi-root',
      '$root',
      '--multi-root-scheme',
      rootScheme,
      '--dart-sdk-summary',
      '${platform}',
      '--output',
      '${toUri(module, dillId)}',
      '--packages-file',
      '$rootScheme:/.packages',
      ...(transitiveDependencies
          .expand((m) => ['--input-linked', '${toUri(m, dillId)}'])),
      ...(module.sources.expand((uri) => ['--source', sourceToImportUri(uri)])),
    ];

    var result = await _runProcess(
        Platform.resolvedExecutable, workerArgs, root.toFilePath());
    _checkExitCode(result, this, module);
  }

  @override
  void notifyCached(Module module) {
    if (_options.verbose) print("cached step: source-to-dill on $module");
  }
}

// Step that invokes the dart2js global analysis on the main module by providing
// the .dill files of all transitive modules as inputs.
class GlobalAnalysisStep implements IOModularStep {
  @override
  List<DataId> get resultData => const [globalDataId, updatedDillId];

  @override
  bool get needsSources => false;

  @override
  List<DataId> get dependencyDataNeeded => const [dillId];

  @override
  List<DataId> get moduleDataNeeded => const [dillId];

  @override
  bool get onlyOnMain => true;

  @override
  Future<void> execute(
      Module module, Uri root, ModuleDataToRelativeUri toUri) async {
    if (_options.verbose) print("step: dart2js global analysis on $module");
    Set<Module> transitiveDependencies = computeTransitiveDependencies(module);
    Iterable<String> dillDependencies =
        transitiveDependencies.map((m) => '${toUri(m, dillId)}');
    var sdkRoot = Platform.script.resolve("../../../../");
    List<String> args = [
      '--packages=${sdkRoot.toFilePath()}/.packages',
      'package:compiler/src/dart2js.dart',
      '${toUri(module, dillId)}',
      '--dill-dependencies=${dillDependencies.join(',')}',
      '--write-data=${toUri(module, globalDataId)}',
      '--out=${toUri(module, updatedDillId)}',
    ];
    var result =
        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());

    _checkExitCode(result, this, module);
  }

  @override
  void notifyCached(Module module) {
    if (_options.verbose)
      print("cached step: dart2js global analysis on $module");
  }
}

// Step that invokes the dart2js backend on the main module given the results of
// the global analysis step.
class Dart2jsBackendStep implements IOModularStep {
  @override
  List<DataId> get resultData => const [jsId];

  @override
  bool get needsSources => false;

  @override
  List<DataId> get dependencyDataNeeded => const [];

  @override
  List<DataId> get moduleDataNeeded => const [updatedDillId, globalDataId];

  @override
  bool get onlyOnMain => true;

  @override
  Future<void> execute(
      Module module, Uri root, ModuleDataToRelativeUri toUri) async {
    if (_options.verbose) print("step: dart2js backend on $module");
    var sdkRoot = Platform.script.resolve("../../../../");
    List<String> args = [
      '--packages=${sdkRoot.toFilePath()}/.packages',
      'package:compiler/src/dart2js.dart',
      '${toUri(module, updatedDillId)}',
      '--read-data=${toUri(module, globalDataId)}',
      '--out=${toUri(module, jsId)}',
    ];
    var result =
        await _runProcess(Platform.resolvedExecutable, args, root.toFilePath());

    _checkExitCode(result, this, module);
  }

  @override
  void notifyCached(Module module) {
    if (_options.verbose) print("cached step: dart2js backend on $module");
  }
}

/// Step that runs the output of dart2js in d8 and saves the output.
class RunD8 implements IOModularStep {
  @override
  List<DataId> get resultData => const [txtId];

  @override
  bool get needsSources => false;

  @override
  List<DataId> get dependencyDataNeeded => const [];

  @override
  List<DataId> get moduleDataNeeded => const [jsId];

  @override
  bool get onlyOnMain => true;

  @override
  Future<void> execute(
      Module module, Uri root, ModuleDataToRelativeUri toUri) async {
    if (_options.verbose) print("step: d8 on $module");
    var sdkRoot = Platform.script.resolve("../../../../");
    List<String> d8Args = [
      sdkRoot
          .resolve('sdk/lib/_internal/js_runtime/lib/preambles/d8.js')
          .toFilePath(),
      root.resolveUri(toUri(module, jsId)).toFilePath(),
    ];
    var result = await _runProcess(
        sdkRoot.resolve(_d8executable).toFilePath(), d8Args, root.toFilePath());

    _checkExitCode(result, this, module);

    await File.fromUri(root.resolveUri(toUri(module, txtId)))
        .writeAsString(result.stdout);
  }

  @override
  void notifyCached(Module module) {
    if (_options.verbose) print("cached step: d8 on $module");
  }
}

void _checkExitCode(ProcessResult result, IOModularStep step, Module module) {
  if (result.exitCode != 0 || _options.verbose) {
    stdout.write(result.stdout);
    stderr.write(result.stderr);
  }
  if (result.exitCode != 0) {
    exitCode = result.exitCode;
    Expect.fail("${step.runtimeType} failed on $module");
  }
}

Future<ProcessResult> _runProcess(
    String command, List<String> arguments, String workingDirectory) {
  if (_options.verbose) {
    print('command:\n$command ${arguments.join(' ')} from $workingDirectory');
  }
  return Process.run(command, arguments, workingDirectory: workingDirectory);
}

String get _d8executable {
  if (Platform.isWindows) {
    return 'third_party/d8/windows/d8.exe';
  } else if (Platform.isLinux) {
    return 'third_party/d8/linux/d8';
  } else if (Platform.isMacOS) {
    return 'third_party/d8/macos/d8';
  }
  throw new UnsupportedError('Unsupported platform.');
}

class _Options {
  bool showSkipped = false;
  bool verbose = false;
  String filter = null;

  static _Options parse(List<String> args) {
    var parser = new ArgParser()
      ..addFlag('verbose',
          abbr: 'v',
          defaultsTo: false,
          help: "print detailed information about the test and modular steps")
      ..addFlag('show-skipped',
          defaultsTo: false,
          help: "print the name of the tests skipped by the filtering option")
      ..addOption('filter',
          help: "only run tests containing this filter as a substring");
    ArgResults argResults = parser.parse(args);
    return _Options()
      ..showSkipped = argResults['show-skipped']
      ..verbose = argResults['verbose']
      ..filter = argResults['filter'];
  }
}
