// Copyright (c) 2016, 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.

library fasta.dill_loader;

import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;

import 'package:kernel/ast.dart' show Class, Component, DartType, Library;

import '../builder/class_builder.dart';
import '../builder/library_builder.dart';
import '../builder/type_builder.dart';

import '../crash.dart' show firstSourceUri;

import '../fasta_codes.dart'
    show SummaryTemplate, Template, templateDillOutlineSummary;

import '../kernel/type_builder_computer.dart' show TypeBuilderComputer;

import '../loader.dart';

import '../messages.dart'
    show
        FormattedMessage,
        LocatedMessage,
        Message,
        noLength,
        SummaryTemplate,
        Template,
        messagePlatformPrivateLibraryAccess,
        templateInternalProblemContextSeverity;

import '../problems.dart' show internalProblem, unhandled;

import '../source/source_loader.dart' show SourceLoader;

import '../ticker.dart' show Ticker;

import 'dill_library_builder.dart' show DillLibraryBuilder;

import 'dill_target.dart' show DillTarget;

import 'dart:collection' show Queue;

class DillLoader extends Loader {
  SourceLoader? currentSourceLoader;

  @override
  final Map<Uri, DillLibraryBuilder> builders = <Uri, DillLibraryBuilder>{};

  final Queue<DillLibraryBuilder> _unparsedLibraries =
      new Queue<DillLibraryBuilder>();

  final List<Library> libraries = <Library>[];

  @override
  final DillTarget target;

  /// List of all handled compile-time errors seen so far by libraries loaded
  /// by this loader.
  ///
  /// A handled error is an error that has been added to the generated AST
  /// already, for example, as a throw expression.
  final List<LocatedMessage> handledErrors = <LocatedMessage>[];

  /// List of all unhandled compile-time errors seen so far by libraries loaded
  /// by this loader.
  ///
  /// An unhandled error is an error that hasn't been handled, see
  /// [handledErrors].
  final List<LocatedMessage> unhandledErrors = <LocatedMessage>[];

  final Set<String> seenMessages = new Set<String>();

  LibraryBuilder? _coreLibrary;

  /// The first library loaded by this [DillLoader].
  // TODO(johnniwinther): Do we need this?
  LibraryBuilder? first;

  int byteCount = 0;

  DillLoader(this.target);

  @override
  LibraryBuilder get coreLibrary => _coreLibrary!;

  void set coreLibrary(LibraryBuilder value) {
    _coreLibrary = value;
  }

  Ticker get ticker => target.ticker;

  /// Look up a library builder by the [uri], or if such doesn't exist, create
  /// one. The canonical URI of the library is [uri], and its actual location is
  /// [fileUri].
  ///
  /// Canonical URIs have schemes like "dart", or "package", and the actual
  /// location is often a file URI.
  ///
  /// The [accessor] is the library that's trying to import, export, or include
  /// as part [uri], and [charOffset] is the location of the corresponding
  /// directive. If [accessor] isn't allowed to access [uri], it's a
  /// compile-time error.
  DillLibraryBuilder read(Uri uri, int charOffset, {LibraryBuilder? accessor}) {
    DillLibraryBuilder builder = builders.putIfAbsent(uri, () {
      DillLibraryBuilder library = target.createLibraryBuilder(uri);
      assert(library.loader == this);
      if (uri.scheme == "dart") {
        if (uri.path == "core") {
          _coreLibrary = library;
        }
      }
      {
        // Add any additional logic after this block. Setting the
        // firstSourceUri and first library should be done as early as
        // possible.
        firstSourceUri ??= uri;
        first ??= library;
      }
      if (_coreLibrary == library) {
        target.loadExtraRequiredLibraries(this);
      }
      if (target.backendTarget.mayDefineRestrictedType(uri)) {
        library.mayImplementRestrictedTypes = true;
      }
      _unparsedLibraries.addLast(library);
      return library;
    });
    if (accessor != null) {
      builder.recordAccess(charOffset, noLength, accessor.fileUri);
      if (!accessor.isPatch &&
          !accessor.isPart &&
          !target.backendTarget
              .allowPlatformPrivateLibraryAccess(accessor.importUri, uri)) {
        accessor.addProblem(messagePlatformPrivateLibraryAccess, charOffset,
            noLength, accessor.fileUri);
      }
    }
    return builder;
  }

  void _ensureCoreLibrary() {
    if (_coreLibrary == null) {
      read(Uri.parse("dart:core"), 0, accessor: first);
      // TODO(askesc): When all backends support set literals, we no longer
      // need to index dart:collection, as it is only needed for desugaring of
      // const sets. We can remove it from this list at that time.
      read(Uri.parse("dart:collection"), 0, accessor: first);
      assert(_coreLibrary != null);
    }
  }

  void buildOutlines() {
    _ensureCoreLibrary();
    while (_unparsedLibraries.isNotEmpty) {
      DillLibraryBuilder library = _unparsedLibraries.removeFirst();
      buildOutline(library);
    }
    _logSummary(outlineSummaryTemplate);
  }

  void _logSummary(Template<SummaryTemplate> template) {
    ticker.log((Duration elapsed, Duration sinceStart) {
      int libraryCount = 0;
      for (DillLibraryBuilder library in builders.values) {
        assert(library.loader == this);
        libraryCount++;
      }
      double ms = elapsed.inMicroseconds / Duration.microsecondsPerMillisecond;
      Message message = template.withArguments(
          libraryCount, byteCount, ms, byteCount / ms, ms / libraryCount);
      print("$sinceStart: ${message.message}");
    });
  }

  /// Register [message] as a problem with a severity determined by the
  /// intrinsic severity of the message.
  // TODO(johnniwinther): Avoid the need for this. If this is ever used, it is
  // inconsistent with messages reported through the [SourceLoader] since they
  // each have their own list of unhandled/unhandled errors and seen messages,
  // and only those of the [SourceLoader] are used elsewhere. Use
  // [currentSourceLoader] to forward messages to the [SourceLoader] instead.
  @override
  FormattedMessage? addProblem(
      Message message, int charOffset, int length, Uri? fileUri,
      {bool wasHandled: false,
      List<LocatedMessage>? context,
      Severity? severity,
      bool problemOnLibrary: false,
      List<Uri>? involvedFiles}) {
    return _addMessage(message, charOffset, length, fileUri, severity,
        wasHandled: wasHandled,
        context: context,
        problemOnLibrary: problemOnLibrary,
        involvedFiles: involvedFiles);
  }

  /// All messages reported by the compiler (errors, warnings, etc.) are routed
  /// through this method.
  ///
  /// Returns a FormattedMessage if the message is new, that is, not previously
  /// reported. This is important as some parser errors may be reported up to
  /// three times by `OutlineBuilder`, `DietListener`, and `BodyBuilder`.
  /// If the message is not new, [null] is reported.
  ///
  /// If [severity] is `Severity.error`, the message is added to
  /// [handledErrors] if [wasHandled] is true or to [unhandledErrors] if
  /// [wasHandled] is false.
  FormattedMessage? _addMessage(Message message, int charOffset, int length,
      Uri? fileUri, Severity? severity,
      {bool wasHandled: false,
      List<LocatedMessage>? context,
      bool problemOnLibrary: false,
      List<Uri>? involvedFiles}) {
    severity ??= message.code.severity;
    if (severity == Severity.ignored) return null;
    String trace = """
message: ${message.message}
charOffset: $charOffset
fileUri: $fileUri
severity: $severity
""";
    if (!seenMessages.add(trace)) return null;
    if (message.code.severity == Severity.context) {
      internalProblem(
          templateInternalProblemContextSeverity
              .withArguments(message.code.name),
          charOffset,
          fileUri);
    }
    target.context.report(
        fileUri != null
            ? message.withLocation(fileUri, charOffset, length)
            : message.withoutLocation(),
        severity,
        context: context,
        involvedFiles: involvedFiles);
    if (severity == Severity.error) {
      (wasHandled ? handledErrors : unhandledErrors).add(fileUri != null
          ? message.withLocation(fileUri, charOffset, length)
          : message.withoutLocation());
    }
    FormattedMessage formattedMessage = target.createFormattedMessage(
        message, charOffset, length, fileUri, context, severity,
        involvedFiles: involvedFiles);
    return formattedMessage;
  }

  Template<SummaryTemplate> get outlineSummaryTemplate =>
      templateDillOutlineSummary;

  /// Append compiled libraries from the given [component]. If the [filter] is
  /// provided, append only libraries whose [Uri] is accepted by the [filter].
  List<DillLibraryBuilder> appendLibraries(Component component,
      {bool Function(Uri uri)? filter, int byteCount: 0}) {
    List<Library> componentLibraries = component.libraries;
    List<Uri> requestedLibraries = <Uri>[];
    List<Uri> requestedLibrariesFileUri = <Uri>[];
    for (int i = 0; i < componentLibraries.length; i++) {
      Library library = componentLibraries[i];
      Uri uri = library.importUri;
      if (filter == null || filter(library.importUri)) {
        libraries.add(library);
        target.registerLibrary(library);
        requestedLibraries.add(uri);
        requestedLibrariesFileUri.add(library.fileUri);
      }
    }
    List<DillLibraryBuilder> result = <DillLibraryBuilder>[];
    for (int i = 0; i < requestedLibraries.length; i++) {
      result.add(read(requestedLibraries[i], -1));
    }
    target.uriToSource.addAll(component.uriToSource);
    this.byteCount += byteCount;
    return result;
  }

  /// Append single compiled library.
  ///
  /// Note that as this only takes a library, no new sources is added to the
  /// uriToSource map.
  DillLibraryBuilder appendLibrary(Library library) {
    // Add to list of libraries in the loader, used for e.g. linking.
    libraries.add(library);

    // Weird interaction begins.
    //
    // Create dill library builder (adds it to a map where it's fetched
    // again momentarily).
    target.registerLibrary(library);
    // Set up the dill library builder (fetch it from the map again, add it to
    // another map and setup some auxiliary things).
    return read(library.importUri, -1);
  }

  void buildOutline(DillLibraryBuilder builder) {
    // ignore: unnecessary_null_comparison
    if (builder.library == null) {
      unhandled("null", "builder.library", 0, builder.fileUri);
    }
    builder.markAsReadyToBuild();
  }

  void finalizeExports({bool suppressFinalizationErrors: false}) {
    for (LibraryBuilder builder in builders.values) {
      DillLibraryBuilder library = builder as DillLibraryBuilder;
      library.markAsReadyToFinalizeExports(
          suppressFinalizationErrors: suppressFinalizationErrors);
    }
  }

  @override
  ClassBuilder computeClassBuilderFromTargetClass(Class cls) {
    Library kernelLibrary = cls.enclosingLibrary;
    LibraryBuilder? library = builders[kernelLibrary.importUri];
    if (library == null) {
      library = currentSourceLoader?.builders[kernelLibrary.importUri];
    }
    return library!.lookupLocalMember(cls.name, required: true) as ClassBuilder;
  }

  @override
  TypeBuilder computeTypeBuilder(DartType type) {
    return type.accept(new TypeBuilderComputer(this));
  }
}
