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

import 'package:_fe_analyzer_shared/src/messages/codes.dart'
    show messageMissingMain;
import 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart'
    show DiagnosticMessageHandler;
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
import 'package:kernel/kernel.dart' show Component;
import 'package:kernel/target/targets.dart' show Target;

import '../api_prototype/compiler_options.dart'
    show CompilerOptions, InvocationMode, Verbosity;
import '../api_prototype/experimental_flags.dart' show ExperimentalFlag;
import '../api_prototype/file_system.dart' show FileSystem, NullFileSystem;
import '../api_prototype/kernel_generator.dart' show CompilerResult;
import '../base/compiler_context.dart' show CompilerContext;
import '../base/processed_options.dart' show ProcessedOptions;
import '../kernel_generator_impl.dart' show generateKernelInternal;
import 'compiler_state.dart' show InitializedCompilerState;
import 'util.dart' show equalLists, equalMaps, equalSets;

export 'package:_fe_analyzer_shared/src/messages/codes.dart'
    show LocatedMessage;
export 'package:_fe_analyzer_shared/src/messages/diagnostic_message.dart'
    show
        DiagnosticMessage,
        DiagnosticMessageHandler,
        getMessageCharOffset,
        getMessageHeaderText,
        getMessageLength,
        getMessageRelatedInformation,
        getMessageUri;
export 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
export 'package:_fe_analyzer_shared/src/parser/async_modifier.dart'
    show AsyncModifier;
export 'package:_fe_analyzer_shared/src/scanner/characters.dart'
    show
        $$,
        $0,
        $9,
        $A,
        $BACKSLASH,
        $CR,
        $DEL,
        $DQ,
        $HASH,
        $LF,
        $LS,
        $PS,
        $TAB,
        $Z,
        $_,
        $a,
        $g,
        $s,
        $z;
export 'package:_fe_analyzer_shared/src/scanner/scanner.dart'
    show isUserDefinableOperator, isMinusOperator;
export 'package:_fe_analyzer_shared/src/util/filenames.dart'
    show nativeToUri, nativeToUriPath, uriPathToNative;
export 'package:_fe_analyzer_shared/src/util/link.dart' show Link, LinkBuilder;
export 'package:_fe_analyzer_shared/src/util/link_implementation.dart'
    show LinkEntry;
export 'package:_fe_analyzer_shared/src/util/relativize.dart'
    show relativizeUri;

export '../api_prototype/compiler_options.dart'
    show
        CompilerOptions,
        InvocationMode,
        Verbosity,
        parseExperimentalFlags,
        parseExperimentalArguments;
export '../api_prototype/const_conditional_simplifier.dart';
export '../api_prototype/constant_evaluator.dart';
export '../api_prototype/experimental_flags.dart'
    show defaultExperimentalFlags, ExperimentalFlag, isExperimentEnabled;
export '../api_prototype/file_system.dart'
    show FileSystem, FileSystemEntity, FileSystemException;
export '../api_prototype/kernel_generator.dart' show kernelForProgram;
export '../api_prototype/language_version.dart'
    show uriUsesLegacyLanguageVersion;
export '../api_prototype/standard_file_system.dart' show DataFileSystemEntity;
export '../api_prototype/try_constant_evaluator.dart';
export '../base/operator.dart' show Operator;
export '../compute_platform_binaries_location.dart'
    show computePlatformBinariesLocation;
export '../kernel/utils.dart' show ByteSink, serializeComponent;
export 'compiler_state.dart' show InitializedCompilerState;

// Coverage-ignore(suite): Not run.
InitializedCompilerState initializeCompiler(
    InitializedCompilerState? oldState,
    Target target,
    Uri? librariesSpecificationUri,
    List<Uri> additionalDills,
    Uri? packagesFileUri,
    {required Map<ExperimentalFlag, bool> explicitExperimentalFlags,
    Map<String, String>? environmentDefines,
    bool verify = false,
    Set<InvocationMode> invocationModes = const <InvocationMode>{},
    Verbosity verbosity = Verbosity.all}) {
  additionalDills.sort((a, b) => a.toString().compareTo(b.toString()));

  // We don't check `target` because it doesn't support '==' and each
  // compilation passes a fresh target. However, we pass a logically identical
  // target each time, so it is safe to assume that it never changes.
  if (oldState != null &&
      oldState.options.packagesFileUri == packagesFileUri &&
      oldState.options.librariesSpecificationUri == librariesSpecificationUri &&
      equalLists(oldState.options.additionalDills, additionalDills) &&
      equalMaps(oldState.options.explicitExperimentalFlags,
          explicitExperimentalFlags) &&
      equalMaps(oldState.options.environmentDefines, environmentDefines) &&
      oldState.options.verify == verify &&
      equalSets(oldState.options.invocationModes, invocationModes) &&
      oldState.options.verbosity == verbosity) {
    return oldState;
  }

  CompilerOptions options = new CompilerOptions()
    ..target = target
    ..additionalDills = additionalDills
    ..librariesSpecificationUri = librariesSpecificationUri
    ..packagesFileUri = packagesFileUri
    ..explicitExperimentalFlags = explicitExperimentalFlags
    ..environmentDefines = environmentDefines
    ..errorOnUnevaluatedConstant = environmentDefines != null ? true : false
    ..verify = verify
    ..invocationModes = invocationModes
    ..verbosity = verbosity;

  ProcessedOptions processedOpts = new ProcessedOptions(options: options);

  return new InitializedCompilerState(options, processedOpts);
}

// Coverage-ignore(suite): Not run.
Future<Component?> compile(
    InitializedCompilerState state,
    bool verbose,
    FileSystem fileSystem,
    DiagnosticMessageHandler onDiagnostic,
    List<Uri> inputs) async {
  assert(inputs.length == 1);
  CompilerOptions options = state.options;
  options
    ..onDiagnostic = onDiagnostic
    ..verbose = verbose
    ..fileSystem = fileSystem;

  ProcessedOptions processedOpts = state.processedOpts;
  processedOpts.inputs.clear();
  processedOpts.inputs.addAll(inputs);
  processedOpts.clearFileSystemCache();

  CompilerResult? compilerResult = await CompilerContext.runWithOptions(
      processedOpts, (CompilerContext context) async {
    CompilerResult compilerResult = await generateKernelInternal(context);
    Component? component = compilerResult.component;
    if (component == null) return null;
    if (component.mainMethod == null) {
      context.options.report(
          context,
          messageMissingMain.withLocation(inputs.single, -1, 0),
          Severity.error);
      return null;
    }
    return compilerResult;
  });

  // Remove these parameters from [options] - they are no longer needed and
  // retain state from the previous compile. (http://dartbug.com/33708)
  options.onDiagnostic = null;
  options.fileSystem = const NullFileSystem();
  return compilerResult?.component;
}
