// Copyright (c) 2023, 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:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/api_prototype/incremental_kernel_generator.dart';
import 'package:kernel/ast.dart';

import 'incremental_suite.dart' as helper;
import 'utils/io_utils.dart' show computeRepoDirUri;

final Uri repoDir = computeRepoDirUri();

void main() async {
  print(await getAllTokens());
}

Future<Set<Class>> getAllTokens() async {
  Uri scannerDir = repoDir.resolve("pkg/_fe_analyzer_shared/lib/src/scanner/");
  return await findIn(Directory.fromUri(scannerDir), "Token", "/token.dart");
}

/// Compiles either a File or a Directory and finds all subtypes of (including)
/// the specified [className] in a file containing [classFilename].
Future<Set<Class>> findIn(
  Directory where,
  String className,
  String classFilename,
) async {
  List<Uri> files = [];
  for (FileSystemEntity subEntity in where.listSync(recursive: true)) {
    if (subEntity is File) {
      if (subEntity.path.toLowerCase().endsWith(".dart")) {
        files.add(subEntity.uri);
      }
    }
  }

  Class? foundTarget;
  Map<Class, Set<Class>> subclassMap = {};
  Component component = await compileOutline(files);
  for (Library lib in component.libraries) {
    for (Class c in lib.classes) {
      if (c.name == className && c.fileUri.toString().contains(classFilename)) {
        if (foundTarget != null) throw "Found both $foundTarget and $c";
        foundTarget = c;
      }
      for (Supertype s in c.supers) {
        (subclassMap[s.classNode] ??= {}).add(c);
      }
    }
  }
  if (foundTarget == null) throw "Didn't find '$className' in '$classFilename'";
  Set<Class> result = {foundTarget};
  List<Class> worklist = [foundTarget];
  while (worklist.isNotEmpty) {
    Class c = worklist.removeLast();
    for (Class child in subclassMap[c] ?? const []) {
      if (result.add(child)) {
        worklist.add(child);
      }
    }
  }
  return result;
}

Future<Component> compileOutline(List<Uri> input) async {
  CompilerOptions options = helper.getOptions();
  options.omitPlatform = true;
  // Give only one input so it automatically finds the packages file.
  helper.TestIncrementalCompiler compiler = new helper.TestIncrementalCompiler(
    options,
    input.first,
    null,
    true,
  );
  IncrementalCompilerResult compilerResult = await compiler.computeDelta(
    entryPoints: input,
  );
  return compilerResult.component;
}
