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

/// An entrypoint used to measure performance of the incremental compiler.
///
/// Given an input a program and a .json file describing edits, this script will
/// first compile the program, then apply edits, recompile the
/// program, and report relevant metrics.
///
/// The edits are encoded as a JSON array:
///  - Each entry in the array is an iteration of edits and holds a list of
///  individual edits. All changes in one iteration are applied at once
///  before calling [IncrementalKernelGenerator.computeDelta].
///
///  - Each edit is a triple declaring a string replacement operation:
///       [uri, from, to]
///
///    Edits are applied in order, so more than on edit is allowed on the same
///    file.
///
///  For example:
///  [
///    {
///      "name" : "big_change",
///      "edits" : [
///        ["input1.dart", "black", "green"],
///        ["input1.dart", "30px", "10px"],
///        ["input2.dart", "a.toString()", ""$a""]
///      ]
///    },
///    {
///      "name" : "small_change",
///      "edits" : [
///        ["input1.dart", "green", "blue"]
///      ]
///    }
///  ]
///
///  Is interpreted as 2 iterations, the first iteration updates input1.dart
///  with 2 changes, and input2.dart with one change. The second iteration
///  updates input1.dart a second time.
library front_end.tool.incremental_perf;

import 'dart:convert';
import 'dart:io' hide FileSystemEntity;
import 'dart:typed_data';

import 'package:args/args.dart';
import 'package:front_end/src/api_prototype/front_end.dart';
import 'package:front_end/src/api_prototype/incremental_kernel_generator.dart';
import 'package:front_end/src/api_prototype/memory_file_system.dart';
import 'package:front_end/src/api_prototype/standard_file_system.dart';
import 'package:front_end/src/base/nnbd_mode.dart';
import 'package:front_end/src/base/processed_options.dart';
import 'package:front_end/src/base/uri_translator.dart';

import 'perf_common.dart';

Future<void> main(List<String> args) async {
  var options = argParser.parse(args);
  if (options.rest.length != 2) {
    throw """
usage: incremental_perf.dart [options] <entry.dart> <edits.json>
${argParser.usage}""";
  }

  var entryUri = _resolveOverlayUri(options.rest[0]);
  var editsUri = Uri.base.resolve(options.rest[1]);
  var changeSets =
      parse(jsonDecode(new File.fromUri(editsUri).readAsStringSync()));
  bool verbose = options["verbose"];
  bool verboseCompilation = options["verbose-compilation"];
  bool isFlutter = options["target"] == "flutter";
  bool useMinimalGenerator = options["implementation"] == "minimal";
  TimingsCollector collector = new TimingsCollector(verbose);

  for (int i = 0; i < 8; i++) {
    await benchmark(
        collector,
        entryUri,
        isFlutter,
        useMinimalGenerator,
        verbose,
        verboseCompilation,
        changeSets,
        options["sdk-summary"],
        options["sdk-library-specification"],
        options["cache"]);
    if (!options["loop"]) break;
  }
  collector.printTimings();
}

Future benchmark(
    TimingsCollector collector,
    Uri entryUri,
    bool isFlutter,
    bool useMinimalGenerator,
    bool verbose,
    bool verboseCompilation,
    List<ChangeSet> changeSets,
    String? sdkSummary,
    String? sdkLibrarySpecification,
    String cache) async {
  var overlayFs = new OverlayFileSystem();
  var compilerOptions = new CompilerOptions()
    ..verbose = verboseCompilation
    ..fileSystem = overlayFs
    ..onDiagnostic = onDiagnosticMessageHandler()
    ..target = createTarget(isFlutter: isFlutter)
    ..nnbdMode = NnbdMode.Weak
    ..environmentDefines = const {};
  if (sdkSummary != null) {
    compilerOptions.sdkSummary = _resolveOverlayUri(sdkSummary);
  }
  if (sdkLibrarySpecification != null) {
    compilerOptions.librariesSpecificationUri =
        _resolveOverlayUri(sdkLibrarySpecification);
  }

  var dir = Directory.systemTemp.createTempSync("ikg-cache");

  final processedOptions =
      new ProcessedOptions(options: compilerOptions, inputs: [entryUri]);
  final UriTranslator uriTranslator = await processedOptions.getUriTranslator();

  collector.start("Initial compilation");
  var generator = new IncrementalKernelGenerator(compilerOptions, [entryUri]);

  var compilerResult = await generator.computeDelta();
  var component = compilerResult.component;
  collector.stop("Initial compilation");
  if (verbose) {
    print("Libraries changed: ${component.libraries.length}");
  }
  if (component.libraries.length < 1) {
    throw "No libraries were changed";
  }

  for (final ChangeSet changeSet in changeSets) {
    String name = "Change '${changeSet.name}' - Incremental compilation";
    await applyEdits(
        changeSet.edits, overlayFs, generator, uriTranslator, verbose);
    collector.start(name);
    compilerResult = await generator.computeDelta();
    component = compilerResult.component;
    collector.stop(name);
    if (verbose) {
      print("Change '${changeSet.name}' - "
          "Libraries changed: ${component.libraries.length}");
    }
    if (component.libraries.length < 1) {
      throw "No libraries were changed";
    }
  }

  dir.deleteSync(recursive: true);
}

/// Apply all edits of a single iteration by updating the copy of the file in
/// the memory file system.
Future<void> applyEdits(
    List<Edit> edits,
    OverlayFileSystem fs,
    IncrementalKernelGenerator generator,
    UriTranslator uriTranslator,
    bool verbose) async {
  for (var edit in edits) {
    if (verbose) {
      print('edit $edit');
    }
    var uri = edit.uri;
    if (uri.isScheme('package')) uri = uriTranslator.translate(uri)!;
    generator.invalidate(uri);
    OverlayFileSystemEntity entity =
        fs.entityForUri(uri) as OverlayFileSystemEntity;
    var contents = await entity.readAsString();
    entity.writeAsStringSync(
        contents.replaceAll(edit.original, edit.replacement));
  }
}

/// Parse a set of edits from a JSON array. See library comment above for
/// details on the format.
List<ChangeSet> parse(List json) {
  final changeSets = <ChangeSet>[];
  for (final Map jsonChangeSet in json) {
    final edits = <Edit>[];
    for (final jsonEdit in jsonChangeSet['edits']) {
      edits.add(new Edit(jsonEdit[0], jsonEdit[1], jsonEdit[2]));
    }
    changeSets.add(new ChangeSet(jsonChangeSet['name'], edits));
  }
  return changeSets;
}

/// An overlay file system that reads the original contents from the physical
/// file system, but performs updates to those files in memory.
///
/// All files in this file system use a custom URI of the form:
///
///   org-dartlang-overlay:///path/to/file.dart
///
/// This special scheme is mainly used to make it clear that the file belongs to
/// this file system and may not correspond to the contents on disk. However,
/// when the file is read for the first time, it will be retrieved from the
/// underlying file system by using the corresponding `file:*` URI:
///
///   file:///path/to/file.dart
class OverlayFileSystem implements FileSystem {
  final MemoryFileSystem memory =
      new MemoryFileSystem(Uri.parse('org-dartlang-overlay:///'));
  final StandardFileSystem physical = StandardFileSystem.instance;

  @override
  FileSystemEntity entityForUri(Uri uri) {
    if (uri.isScheme('org-dartlang-overlay')) {
      return new OverlayFileSystemEntity(uri, this);
    } else if (uri.isScheme('file')) {
      // The IKG compiler reads ".dart_tool/package_config.json" which might
      // contain absolute file URIs (which it will then try to use on the FS).
      // We therefore replace them with overlay-fs URIs as usual.
      return new OverlayFileSystemEntity(_resolveOverlayUri('$uri'), this);
    } else {
      throw "Unsupported scheme: ${uri.scheme}."
          " The OverlayFileSystem only accepts URIs"
          " with the 'org-dartlang-overlay' scheme";
    }
  }
}

class OverlayFileSystemEntity implements FileSystemEntity {
  @override
  final Uri uri;
  FileSystemEntity? _delegate;
  final OverlayFileSystem _fs;

  OverlayFileSystemEntity(this.uri, this._fs);

  Future<FileSystemEntity> get delegate async {
    if (_delegate != null) return _delegate!;
    FileSystemEntity entity = _fs.memory.entityForUri(uri);
    if (await entity.exists()) {
      _delegate = entity;
      return _delegate!;
    }
    return _delegate = _fs.physical.entityForUri(uri.replace(scheme: 'file'));
  }

  @override
  Future<bool> exists() async => (await delegate).exists();

  @override
  Future<bool> existsAsyncIfPossible() async =>
      (await delegate).existsAsyncIfPossible();

  @override
  Future<Uint8List> readAsBytes() async => (await delegate).readAsBytes();

  @override
  Future<List<int>> readAsBytesAsyncIfPossible() async =>
      (await delegate).readAsBytesAsyncIfPossible();

  @override
  Future<String> readAsString() async => (await delegate).readAsString();

  void writeAsStringSync(String contents) =>
      _fs.memory.entityForUri(uri).writeAsStringSync(contents);
}

/// A string replacement edit in a source file.
class Edit {
  final Uri uri;
  final String original;
  final String replacement;

  Edit(String uriString, this.original, this.replacement)
      : uri = _resolveOverlayUri(uriString);

  @override
  String toString() => 'Edit($uri, "$original" -> "$replacement")';
}

/// A named set of changes applied together.
class ChangeSet {
  final String name;
  final List<Edit> edits;

  ChangeSet(this.name, this.edits);

  @override
  String toString() => 'ChangeSet($name, $edits)';
}

Uri _resolveOverlayUri(String uriString) {
  Uri result = Uri.base.resolve(uriString);
  return result.isScheme("file")
      ? result.replace(scheme: 'org-dartlang-overlay')
      : result;
}

ArgParser argParser = new ArgParser()
  ..addFlag('verbose-compilation',
      help: 'make the compiler verbose', defaultsTo: false)
  ..addFlag('verbose', help: 'print additional information', defaultsTo: false)
  ..addFlag('loop', help: 'run benchmark 8 times', defaultsTo: true)
  ..addOption('target',
      help: 'target platform', defaultsTo: 'vm', allowed: ['vm', 'flutter'])
  ..addOption('cache',
      help: 'caching policy used by the compiler',
      defaultsTo: 'protected',
      allowed: ['evicting', 'memory', 'protected'])
  // TODO(johnniwinther): Remove mode option. Legacy mode is no longer
  // supported.
  ..addOption('mode',
      help: 'whether to run in strong or legacy mode',
      defaultsTo: 'strong',
      allowed: ['legacy', 'strong'])
  ..addOption('implementation',
      help: 'incremental compiler implementation to use',
      defaultsTo: 'default',
      allowed: ['default', 'minimal'])
  ..addOption('sdk-summary', help: 'Location of the sdk outline.dill file')
  ..addOption('sdk-library-specification',
      help: 'Location of the '
          'sdk/lib/libraries.json file');
