// 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/base/processed_options.dart';
import 'package:front_end/src/compute_platform_binaries_location.dart'
    show computePlatformBinariesLocation;
import 'package:front_end/src/fasta/compiler_context.dart';
import 'package:front_end/src/fasta/dill/dill_target.dart';
import 'package:front_end/src/fasta/kernel/kernel_target.dart';
import 'package:front_end/src/fasta/ticker.dart';
import 'package:front_end/src/fasta/uri_translator.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/target/targets.dart';
import 'package:vm/modular/target/vm.dart' show VmTarget;

import 'utils/io_utils.dart' show computeRepoDirUri;

final Uri repoDir = computeRepoDirUri();

Set<String> allowlistedExternalDartFiles = {
  "third_party/pkg/package_config/lib/package_config.dart",
  "third_party/pkg/package_config/lib/package_config_types.dart",
  "third_party/pkg/package_config/lib/src/discovery.dart",
  "third_party/pkg/package_config/lib/src/errors.dart",
  "third_party/pkg/package_config/lib/src/package_config_impl.dart",
  "third_party/pkg/package_config/lib/src/package_config_io.dart",
  "third_party/pkg/package_config/lib/src/package_config_json.dart",
  "third_party/pkg/package_config/lib/src/package_config.dart",
  "third_party/pkg/package_config/lib/src/packages_file.dart",
  "third_party/pkg/package_config/lib/src/util.dart",

  // TODO(johnniwinther): Fix to allow dependency of package:package_config.
  "third_party/pkg/package_config/lib/src/util_io.dart",

  // TODO(CFE-team): These files should not be included.
  // The package isn't even in pubspec.yaml.
  "pkg/meta/lib/meta.dart",
  "pkg/meta/lib/meta_meta.dart",
};

/// 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;

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

  List<Uri> result = await CompilerContext.runWithOptions<List<Uri>>(options,
      (CompilerContext c) async {
    UriTranslator uriTranslator = await c.options.getUriTranslator();
    DillTarget dillTarget =
        new DillTarget(ticker, uriTranslator, c.options.target);
    KernelTarget kernelTarget =
        new KernelTarget(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();
    return new List<Uri>.from(c.dependencies);
  });

  Set<Uri> otherDartUris = new Set<Uri>();
  Set<Uri> otherNonDartUris = new Set<Uri>();
  Set<Uri> frontEndUris = new Set<Uri>();
  Set<Uri> kernelUris = new Set<Uri>();
  Set<Uri> vmModularUris = new Set<Uri>();
  Set<Uri> feAnalyzerSharedUris = new Set<Uri>();
  Set<Uri> dartPlatformUris = new Set<Uri>();
  Set<Uri> macrosUris = new Set<Uri>();
  Uri kernelUri = repoDir.resolve("pkg/kernel/");
  Uri vmModularUri = repoDir.resolve("pkg/vm/lib/modular/");
  Uri feAnalyzerSharedUri = repoDir.resolve("pkg/_fe_analyzer_shared/");
  Uri platformUri1 = repoDir.resolve("sdk/lib/");
  Uri platformUri2 = repoDir.resolve("runtime/lib/");
  Uri platformUri3 = repoDir.resolve("runtime/bin/");
  Uri macrosUri = repoDir.resolve("pkg/macros");
  Uri _macrosUri = repoDir.resolve("pkg/_macros");
  for (Uri uri in result) {
    if (uri.toString().startsWith(frontendLibUri.toString())) {
      frontEndUris.add(uri);
    } else if (uri.toString().startsWith(kernelUri.toString())) {
      kernelUris.add(uri);
    } else if (uri.toString().startsWith(vmModularUri.toString())) {
      // For VmTarget for macros.
      vmModularUris.add(uri);
    } else if (uri.toString().startsWith(feAnalyzerSharedUri.toString())) {
      feAnalyzerSharedUris.add(uri);
    } else if (uri.toString().startsWith(platformUri1.toString()) ||
        uri.toString().startsWith(platformUri2.toString()) ||
        uri.toString().startsWith(platformUri3.toString())) {
      dartPlatformUris.add(uri);
    } else if (uri.toString().startsWith(_macrosUri.toString()) ||
        uri.toString().startsWith(macrosUri.toString())) {
      macrosUris.add(uri);
    } else if (uri.toString().endsWith(".dart")) {
      otherDartUris.add(uri);
    } else {
      otherNonDartUris.add(uri);
    }
  }

  // * Everything in frontEndUris is okay --- the frontend can import itself.
  // * Everything in kernel is okay --- the frontend is allowed to
  //   import package:kernel.
  // * Everything in vm/modular is okay, it's specifically for the CFE.
  // * For other entries, remove allowlisted entries.
  // * Everything else is an error.

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

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

  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");
    }
    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;
}
