// Copyright (c) 2021, 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:io';

import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
import 'package:front_end/src/api_prototype/compiler_options.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/util/outline_extractor.dart';
import 'package:kernel/ast.dart';
import 'package:kernel/src/equivalence.dart';
import 'package:kernel/target/targets.dart';
import 'package:package_config/package_config.dart';

import 'incremental_suite.dart' as helper;

Future<void> main(List<String> args) async {
  if (args.length != 1) throw "Wants 1 argument.";
  Uri input = Uri.base.resolve(args.single);
  Uri packageUri = input.resolve(".dart_tool/package_config.json");
  Stopwatch stopwatch = new Stopwatch()..start();
  PackageConfig packageFile = await loadPackageConfigUri(packageUri);
  print("Read packages file in ${stopwatch.elapsedMilliseconds} ms");
  List<Package> packages = packageFile.packages.toList();
  int packageNum = 0;
  for (Package package in packages) {
    packageNum++;
    print(
      "\n\nProcessing package #$packageNum (${package.name}) "
      "of ${packages.length}",
    );
    Directory dir = new Directory.fromUri(package.packageUriRoot);
    List<Uri> uris = [];
    for (FileSystemEntity entry in dir.listSync(recursive: true)) {
      if (entry is File && entry.path.endsWith(".dart")) {
        // Hack.
        String content = entry.readAsStringSync();
        if (content.contains("part of")) continue;
        String asString = "${entry.uri}";
        String packageName = package.name;
        Uri packageUri = package.packageUriRoot;
        String prefix = "${packageUri}";
        if (asString.startsWith(prefix)) {
          Uri reversed = Uri.parse(
            "package:$packageName/${asString.substring(prefix.length)}",
          );
          uris.add(reversed);
        } else {
          throw "Unexpected!";
        }
      }
    }
    print("(found ${uris.length} files)");
    if (uris.isEmpty) continue;
    await processUri(uris, null, packageUri);
  }
  print(" => That's ${packages.length} packages!");

  if (1 + 1 == 2) return;

  Component fullComponent = await processUri([input], null, packageUri);
  List<Uri> uris = fullComponent.libraries.map((l) => l.importUri).toList();
  int i = 0;
  for (Uri uri in uris) {
    i++;
    print("\n\nProcessing $uri (${i} of ${uris.length})");
    try {
      await processUri([uri], fullComponent, packageUri);
    } catch (e, st) {
      print("\n\n-------------\n\n");
      print("Crashed on uri $uri");
      print("Exception: '$e'");
      print(st);
      print("\n\n-------------\n\n");
    }
  }
}

Future<Component> processUri(
  final List<Uri> inputs,
  Component? fullComponent,
  final Uri packageUri,
) async {
  TargetFlags targetFlags = new TargetFlags(trackWidgetCreation: false);
  Target? target = new Dart2jsTarget("dart2js", targetFlags);
  Uri sdkSummary = Uri.base.resolve("out/ReleaseX64/dart2js_outline.dill");
  Stopwatch stopwatch = new Stopwatch()..start();
  Stopwatch extractCompile = new Stopwatch()..start();
  Map<Uri, String> processedFiles = await extractOutline(
    inputs,
    packages: packageUri,
    target: target,
    platform: sdkSummary,
  );
  extractCompile.stop();
  print(
    "Got ${processedFiles.keys.length} files "
    "in ${stopwatch.elapsedMilliseconds} ms",
  );

  Set<Uri> inputsSet = inputs.toSet();

  Stopwatch plainCompile = new Stopwatch()..start();
  List<Library> libs1;
  {
    stopwatch.reset();
    CompilerOptions options = helper.getOptions();
    options.target = target;
    options.sdkSummary = sdkSummary;
    options.packagesFileUri = packageUri;
    helper.TestIncrementalCompiler compiler =
        new helper.TestIncrementalCompiler(
          options,
          inputs.first,
          /* initializeFrom = */ null,
          /* outlineOnly = */ true,
        );
    fullComponent =
        fullComponent ??
        (await compiler.computeDelta(entryPoints: inputs)).component;
    print(
      "Compiled full in ${stopwatch.elapsedMilliseconds} ms "
      "to ${fullComponent.libraries.length} libraries",
    );
    plainCompile.stop();

    libs1 = fullComponent.libraries
        .where((element) => inputsSet.contains(element.importUri))
        .toList();
  }
  List<Library> libs2;
  {
    stopwatch.reset();
    extractCompile.start();
    CompilerOptions options = helper.getOptions();
    options.target = target;
    options.sdkSummary = sdkSummary;
    options.packagesFileUri = packageUri;
    MemoryFileSystem mfs = new MemoryFileSystem(Uri.base);
    mfs
        .entityForUri(packageUri)
        .writeAsBytesSync(
          await options.fileSystem.entityForUri(packageUri).readAsBytes(),
        );
    if (options.sdkSummary != null) {
      mfs
          .entityForUri(options.sdkSummary!)
          .writeAsBytesSync(
            await options.fileSystem
                .entityForUri(options.sdkSummary!)
                .readAsBytes(),
          );
    }
    if (options.librariesSpecificationUri != null) {
      mfs
          .entityForUri(options.librariesSpecificationUri!)
          .writeAsBytesSync(
            await options.fileSystem
                .entityForUri(options.librariesSpecificationUri!)
                .readAsBytes(),
          );
    }
    for (MapEntry<Uri, String> entry in processedFiles.entries) {
      mfs.entityForUri(entry.key).writeAsStringSync(entry.value);
    }
    options.fileSystem = mfs;
    helper.TestIncrementalCompiler compiler =
        new helper.TestIncrementalCompiler(
          options,
          inputs.first,
          /* initializeFrom = */ null,
          /* outlineOnly = */ true,
        );
    IncrementalCompilerResult c = await compiler.computeDelta(
      entryPoints: inputs,
    );
    print(
      "Compiled outlined in ${stopwatch.elapsedMilliseconds} ms "
      "to ${c.component.libraries.length} libraries",
    );
    extractCompile.stop();

    libs2 = c.component.libraries
        .where((element) => inputsSet.contains(element.importUri))
        .toList();
  }

  int libSorter(Library a, Library b) {
    return a.importUri.toString().compareTo(b.importUri.toString());
  }

  libs1.sort(libSorter);
  libs2.sort(libSorter);
  if (libs1.length != libs2.length) {
    print("Bad:");
    print(
      "Not the same amount of libraries: ${libs1.length} vs ${libs2.length}",
    );
    throw "bad result for $inputs";
  }
  List<EquivalenceResult> badResults = [];
  for (int i = 0; i < libs1.length; i++) {
    EquivalenceResult result = checkEquivalence(
      libs1[i],
      libs2[i],
      strategy: const Strategy(),
    );
    if (!result.isEquivalent) {
      badResults.add(result);
    }
  }

  if (badResults.isEmpty) {
    print("OK");
  } else {
    print("Bad:");
    for (EquivalenceResult badResult in badResults) {
      print(badResult);
      print("---");
    }
    // globalDebuggingNames = new NameSystem();
    // print(lib1.leakingDebugToString());
    // print("\n---\nvs\n----\n");
    // globalDebuggingNames = new NameSystem();
    // print(lib2.leakingDebugToString());
    throw "bad result for $inputs";
  }

  if (plainCompile.elapsedMilliseconds > extractCompile.elapsedMilliseconds) {
    print(
      "=> Plain compile slower! "
      "(${plainCompile.elapsedMilliseconds} vs "
      "${extractCompile.elapsedMilliseconds})",
    );
  } else {
    print(
      "=> Plain compile faster! "
      "(${plainCompile.elapsedMilliseconds} vs "
      "${extractCompile.elapsedMilliseconds})",
    );
  }

  return fullComponent;
}

class Strategy extends EquivalenceStrategy {
  const Strategy();

  @override
  bool checkTreeNode_fileOffset(
    EquivalenceVisitor visitor,
    TreeNode node,
    TreeNode other,
  ) {
    return true;
  }

  @override
  bool checkAssertStatement_conditionStartOffset(
    EquivalenceVisitor visitor,
    AssertStatement node,
    AssertStatement other,
  ) {
    return true;
  }

  @override
  bool checkAssertStatement_conditionEndOffset(
    EquivalenceVisitor visitor,
    AssertStatement node,
    AssertStatement other,
  ) {
    return true;
  }

  @override
  bool checkClass_startFileOffset(
    EquivalenceVisitor visitor,
    Class node,
    Class other,
  ) {
    return true;
  }

  @override
  bool checkClass_fileEndOffset(
    EquivalenceVisitor visitor,
    Class node,
    Class other,
  ) {
    return true;
  }

  @override
  bool checkProcedure_fileStartOffset(
    EquivalenceVisitor visitor,
    Procedure node,
    Procedure other,
  ) {
    return true;
  }

  @override
  bool checkConstructor_startFileOffset(
    EquivalenceVisitor visitor,
    Constructor node,
    Constructor other,
  ) {
    return true;
  }

  @override
  bool checkMember_fileEndOffset(
    EquivalenceVisitor visitor,
    Member node,
    Member other,
  ) {
    return true;
  }

  @override
  bool checkFunctionNode_fileEndOffset(
    EquivalenceVisitor visitor,
    FunctionNode node,
    FunctionNode other,
  ) {
    return true;
  }

  @override
  bool checkBlock_fileEndOffset(
    EquivalenceVisitor visitor,
    Block node,
    Block other,
  ) {
    return true;
  }

  @override
  bool checkLibrary_additionalExports(
    EquivalenceVisitor visitor,
    Library node,
    Library other,
  ) {
    return visitor.checkSets(
      node.additionalExports.toSet(),
      other.additionalExports.toSet(),
      visitor.matchReferences,
      visitor.checkReferences,
      'additionalExports',
    );
  }

  @override
  bool checkClass_procedures(
    EquivalenceVisitor visitor,
    Class node,
    Class other,
  ) {
    // Check procedures as a set instead of a list to allow for reordering.
    List<Procedure> a = node.procedures.toList();
    int sorter(Procedure x, Procedure y) {
      int result = x.name.text.compareTo(y.name.text);
      if (result != 0) return result;
      result = x.kind.index - y.kind.index;
      if (result != 0) return result;
      // other stuff?
      return 0;
    }

    a.sort(sorter);
    List<Procedure> b = other.procedures.toList();
    b.sort(sorter);
    // return visitor.checkSets(a.toSet(), b.toSet(),
    //     visitor.matchNamedNodes, visitor.checkNodes, 'procedures');

    return visitor.checkLists(a, b, visitor.checkNodes, 'procedures');
  }
}
