// Copyright (c) 2017, 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.compiler_context;

import 'dart:async' show Zone, runZoned;

import 'package:_fe_analyzer_shared/src/messages/codes.dart';
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
import 'package:_fe_analyzer_shared/src/scanner/string_canonicalizer.dart'
    show clearStringCanonicalizationCache;
import 'package:_fe_analyzer_shared/src/util/colors.dart' as colors;
import 'package:kernel/ast.dart' show Source;

import '../api_prototype/file_system.dart' show FileSystem;
import '../base/processed_options.dart' show ProcessedOptions;
import 'command_line_reporting.dart' as command_line_reporting;

final Object compilerContextKey = new Object();

/// Shared context used throughout the compiler.
///
/// The compiler works with a single instance of this class. To avoid
/// passing it around as an argument everywhere, it is stored as a zone-value.
///
/// For convenience the static getter [CompilerContext.current] retrieves the
/// context stored in the current zone.
class CompilerContext {
  // TODO(sigmund): Move here any method in ProcessedOptions that doesn't seem
  // appropriate as an "option", or consider merging ProcessedOptions entirely
  // within this class, and depend only on the raw options here.
  final ProcessedOptions options;

  /// Sources seen by the compiler.
  ///
  /// This is populated as the compiler reads files, and it is used for error
  /// reporting and to generate source location information in the compiled
  /// programs.
  final Map<Uri, Source> uriToSource = <Uri, Source>{};

  FileSystem get fileSystem => options.fileSystem;

  Uri? cachedSdkRoot = null;

  bool compilingPlatform = false;

  CompilerContext(this.options) {
    if (options.verbose) {
      colors.printEnableColorsReason = print;
    }
  }

  /// Report [message], for example, by printing it.
  void report(LocatedMessage message, Severity severity,
      {List<LocatedMessage>? context, List<Uri>? involvedFiles}) {
    options.report(message, severity,
        context: context, involvedFiles: involvedFiles);
  }

  /// Report [message], for example, by printing it.
  // TODO(askesc): Remove this and direct callers directly to report.
  void reportWithoutLocation(Message message, Severity severity) {
    options.reportWithoutLocation(message, severity);
  }

  /// Format [message] as a text string that can be included in generated code.
  PlainAndColorizedString format(LocatedMessage message, Severity severity) {
    return command_line_reporting.format(message, severity);
  }

  static CompilerContext get current {
    CompilerContext? context = Zone.current[compilerContextKey];
    if (context == null) {
      // Coverage-ignore-block(suite): Not run.
      // Note: we throw directly and don't use internalProblem, because
      // internalProblem depends on having a compiler context available.
      String problemMessage =
          messageInternalProblemMissingContext.problemMessage;
      String correctionMessage =
          messageInternalProblemMissingContext.correctionMessage!;
      throw "Internal problem: $problemMessage\nTip: $correctionMessage";
    }
    return context;
  }

  static bool get isActive => Zone.current[compilerContextKey] != null;

  /// Perform [action] in a [Zone] where this [CompilerContext] will be
  /// available as `CompilerContext.current`.
  Future<T> runInContext<T>(Future<T> action(CompilerContext c)) {
    return runZoned(
        () => new Future<T>.sync(() => action(this)).whenComplete(clear),
        zoneValues: {compilerContextKey: this});
  }

  /// Perform [action] in a [Zone] where [options] will be available as
  /// `CompilerContext.current.options`.
  static Future<T> runWithOptions<T>(
      ProcessedOptions options, Future<T> action(CompilerContext c),
      {bool errorOnMissingInput = true}) {
    return new CompilerContext(options)
        .runInContext<T>((CompilerContext c) async {
      await options.validateOptions(errorOnMissingInput: errorOnMissingInput);
      return action(c);
    });
  }

  static Future<T> runWithDefaultOptions<T>(
      Future<T> action(CompilerContext c)) {
    return new CompilerContext(new ProcessedOptions()).runInContext<T>(action);
  }

  void clear() {
    clearStringCanonicalizationCache();
  }
}
