// 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');
  }
}
