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

import "dart:developer";
import 'dart:io' show Platform;

import 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/api_prototype/experimental_flags.dart';
import 'package:front_end/src/fasta/kernel/utils.dart';

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

import 'incremental_load_from_dill_suite.dart' as helper;

import "incremental_utils.dart" as util;

main(List<String> args) async {
  bool fast = false;
  bool useExperimentalInvalidation = false;
  bool addDebugBreaks = false;
  int limit = -1;
  for (String arg in args) {
    if (arg == "--fast") {
      fast = true;
    } else if (arg == "--experimental") {
      useExperimentalInvalidation = true;
    } else if (arg == "--addDebugBreaks") {
      addDebugBreaks = true;
    } else if (arg.startsWith("--limit=")) {
      limit = int.parse(arg.substring("--limit=".length));
    } else {
      throw "Unsupported argument: $arg";
    }
  }

  Dart2jsTester dart2jsTester = new Dart2jsTester(
      useExperimentalInvalidation, fast, addDebugBreaks, limit);
  await dart2jsTester.test();
}

class Dart2jsTester {
  final bool useExperimentalInvalidation;
  final bool fast;
  final bool addDebugBreaks;
  final int limit;

  Stopwatch stopwatch = new Stopwatch();
  List<int> firstCompileData;
  Map<Uri, List<int>> libToData;
  List<Uri> uris;

  List<Uri> diffs = new List<Uri>();
  Set<Uri> componentUris = new Set<Uri>();

  Dart2jsTester(this.useExperimentalInvalidation, this.fast,
      this.addDebugBreaks, this.limit);

  void test() async {
    helper.TestIncrementalCompiler compiler = await setup();
    if (addDebugBreaks) {
      debugger();
    }

    diffs = new List<Uri>();
    componentUris = new Set<Uri>();

    Stopwatch localStopwatch = new Stopwatch()..start();
    int recompiles = 0;
    for (int i = 0; i < uris.length; i++) {
      if (limit >= 0 && limit < i) break;
      recompiles++;
      Uri uri = uris[i];
      await step(uri, i, compiler, localStopwatch);
    }

    print("A total of ${diffs.length} diffs:");
    for (Uri uri in diffs) {
      print(" - $uri");
    }

    print("Done after ${recompiles} recompiles in "
        "${stopwatch.elapsedMilliseconds} ms");
  }

  Future step(Uri uri, int i, helper.TestIncrementalCompiler compiler,
      Stopwatch localStopwatch) async {
    print("Invalidating $uri ($i)");
    compiler.invalidate(uri);
    localStopwatch.reset();
    Component c2 = await compiler.computeDelta(fullComponent: true);
    print("Recompiled in ${localStopwatch.elapsedMilliseconds} ms");
    print("invalidatedImportUrisForTesting: "
        "${compiler.invalidatedImportUrisForTesting}");
    print("rebuildBodiesCount: ${compiler.rebuildBodiesCount}");
    localStopwatch.reset();
    Set<Uri> thisUris = new Set<Uri>.from(c2.libraries.map((l) => l.importUri));
    if (componentUris.isNotEmpty) {
      Set<Uri> diffUris = {};
      diffUris.addAll(thisUris.difference(componentUris));
      diffUris.addAll(componentUris.difference(thisUris));
      if (diffUris.isNotEmpty) {
        print("Diffs for this compile: $diffUris");
      }
    }
    componentUris.clear();
    componentUris.addAll(thisUris);

    if (fast) {
      print("Got ${c2.libraries.length} libraries");
      c2.libraries.sort((l1, l2) {
        return "${l1.fileUri}".compareTo("${l2.fileUri}");
      });

      c2.problemsAsJson?.sort();

      c2.computeCanonicalNames();

      int foundCount = 0;
      for (Library library in c2.libraries) {
        Set<Uri> uris = new Set<Uri>();
        uris.add(library.importUri);
        for (LibraryPart part in library.parts) {
          Uri uri = library.importUri.resolve(part.partUri);
          uris.add(uri);
        }
        if (!uris.contains(uri)) continue;
        foundCount++;
        library.additionalExports.sort((Reference r1, Reference r2) {
          return "${r1.canonicalName}".compareTo("${r2.canonicalName}");
        });
        library.problemsAsJson?.sort();

        List<int> libSerialized =
            serializeComponent(c2, filter: (l) => l == library);
        if (!isEqual(libToData[library.importUri], libSerialized)) {
          print("=====");
          print("=====");
          print("=====");
          print("Notice diff on $uri ($i)!");
          libToData[library.importUri] = libSerialized;
          diffs.add(uri);
          print("=====");
          print("=====");
          print("=====");
        }
      }
      if (foundCount != 1) {
        throw "Expected to find $uri, but it $foundCount times.";
      }
      print("Serialized library in ${localStopwatch.elapsedMilliseconds} ms");
    } else {
      List<int> thisCompileData = util.postProcess(c2);
      print("Serialized in ${localStopwatch.elapsedMilliseconds} ms");
      if (!isEqual(firstCompileData, thisCompileData)) {
        print("=====");
        print("=====");
        print("=====");
        print("Notice diff on $uri ($i)!");
        firstCompileData = thisCompileData;
        diffs.add(uri);
        print("=====");
        print("=====");
        print("=====");
      }
    }
    if (addDebugBreaks) {
      debugger();
    }
    print("-----");
  }

  Future<helper.TestIncrementalCompiler> setup() async {
    stopwatch.reset();
    stopwatch.start();
    Uri input = Platform.script.resolve("../../compiler/bin/dart2js.dart");
    CompilerOptions options = helper.getOptions();
    options.experimentalFlags[ExperimentalFlag
        .alternativeInvalidationStrategy] = useExperimentalInvalidation;
    helper.TestIncrementalCompiler compiler =
        new helper.TestIncrementalCompiler(options, input);
    Component c = await compiler.computeDelta();
    print("Compiled dart2js to Component with ${c.libraries.length} libraries "
        "in ${stopwatch.elapsedMilliseconds} ms.");
    stopwatch.reset();
    if (fast) {
      libToData = {};
      c.libraries.sort((l1, l2) {
        return "${l1.fileUri}".compareTo("${l2.fileUri}");
      });

      c.problemsAsJson?.sort();

      c.computeCanonicalNames();

      for (Library library in c.libraries) {
        library.additionalExports.sort((Reference r1, Reference r2) {
          return "${r1.canonicalName}".compareTo("${r2.canonicalName}");
        });
        library.problemsAsJson?.sort();

        List<int> libSerialized =
            serializeComponent(c, filter: (l) => l == library);
        libToData[library.importUri] = libSerialized;
      }
    } else {
      firstCompileData = util.postProcess(c);
    }
    print("Serialized in ${stopwatch.elapsedMilliseconds} ms");
    stopwatch.reset();

    uris = c.uriToSource.values
        .map((s) => s != null ? s.importUri : null)
        .where((u) => u != null && u.scheme != "dart")
        .toSet()
        .toList();

    c = null;

    return compiler;
  }

  bool isEqual(List<int> a, List<int> b) {
    int length = a.length;
    if (b.length != length) {
      return false;
    }
    for (int i = 0; i < length; ++i) {
      if (a[i] != b[i]) {
        return false;
      }
    }
    return true;
  }
}
