// 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_suite.dart' as helper;

import "incremental_utils.dart" as util;

Future<void> 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();
  late List<int> firstCompileData;
  late Map<Uri, List<int>> libToData;
  late List<Uri> uris;

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

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

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

    diffs = <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.explicitExperimentalFlags[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.importUri)
        .whereType<Uri>()
        .where((u) => 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;
  }
}
