// 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:io';

import 'package:_fe_analyzer_shared/src/messages/severity.dart';
import 'package:expect/expect.dart' show Expect;
import 'package:front_end/src/api_prototype/compiler_options.dart';
import 'package:front_end/src/api_prototype/standard_file_system.dart';
import 'package:front_end/src/base/compiler_context.dart';
import 'package:front_end/src/base/file_system_dependency_tracker.dart';
import 'package:front_end/src/base/import_chains.dart';
import 'package:front_end/src/base/processed_options.dart';
import 'package:front_end/src/base/ticker.dart';
import 'package:front_end/src/base/uri_translator.dart';
import 'package:front_end/src/builder/library_builder.dart';
import 'package:front_end/src/compute_platform_binaries_location.dart'
    show computePlatformBinariesLocation;
import 'package:front_end/src/dill/dill_target.dart';
import 'package:front_end/src/kernel/kernel_target.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/target/targets.dart';
import 'package:package_config/src/package_config.dart';
import 'package:vm/modular/target/vm.dart' show VmTarget;

import 'utils/io_utils.dart' show computeRepoDirUri;

final Uri repoDir = computeRepoDirUri();

Set<String> allowlistedExternalDartFiles = {
  // TODO(CFE-team): These files should not be included.
  // The package isn't even in pubspec.yaml.
  // They're included via at least
  // _fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
  "pkg/meta/lib/meta.dart",
  "pkg/meta/lib/meta_meta.dart",
};

Set<String> allowedPackages = {
  "front_end",
  "kernel",
  "_fe_analyzer_shared",
  "package_config",
  "macros",
  "_macros",
  // package:front_end imports package:yaml for the 'dynamic modules'
  // experiment.
  "yaml",
  // package:yaml uses package:source_span, package:string_scanner and
  // package:collection.
  "source_span",
  "string_scanner",
  "collection",
  // package:source_span imports package:path.
  "path",
  // package:source_span imports package:term_glyph.
  "term_glyph",
};

List<String> allowedRelativePaths = [
  // For VmTarget for macros.
  "pkg/vm/lib/modular/",
  // Platform.
  "sdk/lib/",
];

/// Returns true on no errors and false if errors was found.
Future<bool> main() async {
  Ticker ticker = new Ticker(isVerbose: false);
  CompilerOptions compilerOptions = getOptions();

  Uri packageConfigUri = repoDir.resolve(".dart_tool/package_config.json");
  if (!new File.fromUri(packageConfigUri).existsSync()) {
    throw "Couldn't find .dart_tool/package_config.json";
  }
  compilerOptions.packagesFileUri = packageConfigUri;
  FileSystemDependencyTracker tracker = new FileSystemDependencyTracker();
  compilerOptions.fileSystem = StandardFileSystem.instanceWithTracking(tracker);

  ProcessedOptions options = new ProcessedOptions(options: compilerOptions);

  Uri frontendLibUri = repoDir.resolve("pkg/front_end/lib/");
  List<FileSystemEntity> entities =
      new Directory.fromUri(frontendLibUri).listSync(recursive: true);
  for (FileSystemEntity entity in entities) {
    if (entity is File && entity.path.endsWith(".dart")) {
      options.inputs.add(entity.uri);
    }
  }

  LoadedLibraries? loadedLibraries;
  Map<Uri, Uri> fileUriToImportUri = {};
  List<String> allowedUriPrefixes = [
    for (String relativePath in allowedRelativePaths)
      repoDir.resolve(relativePath).toString()
  ];

  List<Uri> result = await CompilerContext.runWithOptions<List<Uri>>(options,
      (CompilerContext c) async {
    UriTranslator uriTranslator = await c.options.getUriTranslator();
    for (Package package in uriTranslator.packages.packages) {
      if (allowedPackages.contains(package.name)) {
        allowedUriPrefixes.add(package.packageUriRoot.toString());
      }
    }
    DillTarget dillTarget =
        new DillTarget(c, ticker, uriTranslator, c.options.target);
    KernelTarget kernelTarget =
        new KernelTarget(c, c.fileSystem, false, dillTarget, uriTranslator);
    Uri? platform = c.options.sdkSummary;
    if (platform != null) {
      var bytes = new File.fromUri(platform).readAsBytesSync();
      var platformComponent = loadComponentFromBytes(bytes);
      dillTarget.loader
          .appendLibraries(platformComponent, byteCount: bytes.length);
    }

    kernelTarget.setEntryPoints(c.options.inputs);
    dillTarget.buildOutlines();
    await kernelTarget.loader.buildOutlines();

    {
      List<CompilationUnit> compilationUnits =
          kernelTarget.loader.compilationUnits.toList(growable: false);
      List<CompilationUnit> rootCompilationUnits = [];
      Set<Uri> inputs = new Set.of(options.inputs);
      for (CompilationUnit unit in compilationUnits) {
        fileUriToImportUri[unit.fileUri] = unit.importUri;
        if (inputs.contains(unit.fileUri) || inputs.contains(unit.importUri)) {
          rootCompilationUnits.add(unit);
        }
      }
      loadedLibraries =
          new LoadedLibrariesImpl(rootCompilationUnits, compilationUnits);
    }

    return new List<Uri>.from(tracker.dependencies);
  });

  Set<Uri> otherDartUris = new Set<Uri>();
  Set<Uri> otherNonDartUris = new Set<Uri>();
  for (Uri uri in result) {
    final String uriAsString = uri.toString();
    bool allowed = false;
    for (String prefix in allowedUriPrefixes) {
      if (uriAsString.startsWith(prefix)) {
        allowed = true;
        break;
      }
    }
    if (!allowed) {
      if (uri.toString().endsWith(".dart")) {
        otherDartUris.add(uri);
      } else {
        otherNonDartUris.add(uri);
      }
    }
  }

  // Remove allow-listed non-dart files.
  otherNonDartUris.remove(packageConfigUri);
  otherNonDartUris.remove(repoDir.resolve("sdk/lib/libraries.json"));

  // Remove allow-listed dart files.
  for (String s in allowlistedExternalDartFiles) {
    otherDartUris.remove(repoDir.resolve(s));
  }

  // Everything else is an error.
  if (otherNonDartUris.isNotEmpty || otherDartUris.isNotEmpty) {
    print("The following files was imported without being allowlisted:");
    for (Uri uri in otherNonDartUris) {
      print(" - $uri");
    }
    for (Uri uri in otherDartUris) {
      print(" - $uri");
      if (loadedLibraries != null) {
        Uri? importUri = fileUriToImportUri[uri];
        if (importUri != null) {
          Set<String> importChains = (computeImportChainsFor(
              Uri.parse("<entry>"), loadedLibraries!, importUri,
              verbose: false));
          for (String s in importChains) {
            print(" => $s");
          }
        }
      }
    }
    exitCode = 1;
    return false;
  }
  return true;
}

CompilerOptions getOptions() {
  // Compile sdk because when this is run from a lint it uses the checked-in sdk
  // and we might not have a suitable compiled platform.dill file.
  Uri sdkRoot = computePlatformBinariesLocation(forceBuildDir: true);
  CompilerOptions options = new CompilerOptions()
    ..sdkRoot = sdkRoot
    ..compileSdk = true
    ..target = new VmTarget(new TargetFlags())
    ..librariesSpecificationUri = repoDir.resolve("sdk/lib/libraries.json")
    ..omitPlatform = true
    ..onDiagnostic = (DiagnosticMessage message) {
      if (message.severity == Severity.error) {
        Expect.fail(
            "Unexpected error: ${message.plainTextFormatted.join('\n')}");
      }
    }
    ..environmentDefines = const {};
  return options;
}
