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

// @dart = 2.9

import 'dart:io' show Directory, File, Platform, Process, ProcessResult;

import 'dart:typed_data' show Uint8List;

import 'package:front_end/src/fasta/kernel/utils.dart' show serializeComponent;

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

import 'package:kernel/binary/ast_from_binary.dart' show BinaryBuilder;

import 'package:kernel/target/targets.dart' show TargetFlags;

import "package:vm/target/vm.dart" show VmTarget;

import 'incremental_suite.dart' show getOptions, normalCompileToComponent;

import 'utils/io_utils.dart' show computeRepoDir;

Future<void> main() async {
  final Uri dart2jsUrl = Uri.base.resolve("pkg/compiler/bin/dart2js.dart");
  Stopwatch stopwatch = new Stopwatch()..start();
  Component component = await normalCompileToComponent(dart2jsUrl,
      options: getOptions()
        ..target = new VmTarget(new TargetFlags())
        ..omitPlatform = false);
  print("Compiled dart2js in ${stopwatch.elapsedMilliseconds} ms");

  component.computeCanonicalNames();

  stopwatch.reset();
  List<List<int>> libComponents = <List<int>>[];
  for (Library lib in component.libraries) {
    Component libComponent = new Component(nameRoot: component.root);
    libComponent.libraries.add(lib);
    libComponent.uriToSource.addAll(component.uriToSource);
    libComponent.setMainMethodAndMode(
        component.mainMethodName, true, component.mode);
    libComponents.add(serializeComponent(libComponent));
  }
  print("Serialized ${libComponents.length} separate library components "
      "in ${stopwatch.elapsedMilliseconds} ms");

  stopwatch.reset();
  int totalLength = 0;
  for (List<int> libComponent in libComponents) {
    totalLength += libComponent.length;
  }
  Uint8List combined = new Uint8List(totalLength);
  int index = 0;
  for (List<int> libComponent in libComponents) {
    combined.setRange(index, index + libComponent.length, libComponent);
    index += libComponent.length;
  }
  print("Combined in ${stopwatch.elapsedMilliseconds} ms");

  stopwatch.reset();
  Component combinedComponent = new Component();
  new BinaryBuilder(combined).readComponent(combinedComponent);
  print("Read combined in ${stopwatch.elapsedMilliseconds} ms");

  stopwatch.reset();
  Uint8List merged = serializeComponent(combinedComponent);
  print("Serialized combined component in ${stopwatch.elapsedMilliseconds} ms");

  for (Uint8List data in [combined, merged]) {
    stopwatch.reset();
    Directory out = Directory.systemTemp.createTempSync("split_dill_test");
    try {
      File f = new File.fromUri(out.uri.resolve("out.dill"));
      f.writeAsBytesSync(data);

      ProcessResult result = await Process.run(
          dartVm,
          [
            "--compile_all",
            f.path,
            "-h",
          ],
          workingDirectory: out.path);
      print("stdout: ${result.stdout}");
      print("stderr: ${result.stderr}");
      print("Exit code: ${result.exitCode}");
      if (result.exitCode != 0) {
        throw "Got exit code ${result.exitCode}";
      }
      print("Ran VM on dill in ${stopwatch.elapsedMilliseconds} ms");
    } finally {
      out.deleteSync(recursive: true);
    }
  }
}

final String repoDir = computeRepoDir();

String get dartVm => Platform.resolvedExecutable;
