// Copyright (c) 2021, 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 'api.dart';
// ignore: unused_import
import 'bootstrap.dart'; // For doc comments only.
import 'executor/serialization.dart';

/// The interface used by Dart language implementations, in order to load
/// and execute macros, as well as produce library augmentations from those
/// macro applications.
///
/// This class more clearly defines the role of a Dart language implementation
/// during macro discovery and expansion, and unifies how augmentation libraries
/// are produced.
abstract class MacroExecutor {
  /// Creates an instance of the macro [name] from [library] in the executor,
  /// and returns an identifier for that instance.
  ///
  /// Throws an exception if an instance is not created.
  ///
  /// Instances may be re-used throughout a single build, but should be
  /// re-created on subsequent builds (even incremental ones).
  Future<MacroInstanceIdentifier> instantiateMacro(
      Uri library, String name, String constructor, Arguments arguments);

  /// Runs the type phase for [macro] on a given [declaration].
  ///
  /// Throws an exception if there is an error executing the macro.
  Future<MacroExecutionResult> executeTypesPhase(MacroInstanceIdentifier macro,
      covariant Declaration declaration, IdentifierResolver identifierResolver);

  /// Runs the declarations phase for [macro] on a given [declaration].
  ///
  /// Throws an exception if there is an error executing the macro.
  Future<MacroExecutionResult> executeDeclarationsPhase(
      MacroInstanceIdentifier macro,
      covariant Declaration declaration,
      IdentifierResolver identifierResolver,
      TypeResolver typeResolver,
      ClassIntrospector classIntrospector);

  /// Runs the definitions phase for [macro] on a given [declaration].
  ///
  /// Throws an exception if there is an error executing the macro.
  Future<MacroExecutionResult> executeDefinitionsPhase(
      MacroInstanceIdentifier macro,
      covariant Declaration declaration,
      IdentifierResolver identifierResolver,
      TypeResolver typeResolver,
      ClassIntrospector classIntrospector,
      TypeDeclarationResolver typeDeclarationResolver,
      TypeInferrer typeInferrer);

  /// Combines multiple [MacroExecutionResult]s into a single library
  /// augmentation file, and returns a [String] representing that file.
  ///
  /// The [resolveIdentifier] argument should return the import uri to be used
  /// for that identifier.
  ///
  /// The [inferOmittedType] argument is used to get the inferred type for a
  /// given [OmittedTypeAnnotation].
  ///
  /// If [omittedTypes] is provided, [inferOmittedType] is allowed to return
  /// `null` for types that have not yet been inferred. In this case a fresh
  /// name will be used for the omitted type in the generated library code and
  /// the omitted type will be mapped to the fresh name in [omittedTypes].
  ///
  /// The generated library files content must be deterministic, including the
  /// generation of fresh names for import prefixes and omitted types.
  String buildAugmentationLibrary(
      Iterable<MacroExecutionResult> macroResults,
      ResolvedIdentifier Function(Identifier) resolveIdentifier,
      TypeAnnotation? Function(OmittedTypeAnnotation) inferOmittedType,
      {Map<OmittedTypeAnnotation, String>? omittedTypes});

  /// Tell the executor to shut down and clean up any resources it may have
  /// allocated.
  Future<void> close();
}

/// The arguments passed to a macro constructor.
///
/// All argument instances must be of type [Code] or a built-in value type that
/// is serializable (num, bool, String, null, etc).
class Arguments implements Serializable {
  final List<Object?> positional;

  final Map<String, Object?> named;

  Arguments(this.positional, this.named);

  factory Arguments.deserialize(Deserializer deserializer) {
    deserializer
      ..moveNext()
      ..expectList();
    List<Object?> positionalArgs = [
      for (bool hasNext = deserializer.moveNext();
          hasNext;
          hasNext = deserializer.moveNext())
        _deserializeArg(deserializer, alreadyMoved: true),
    ];
    deserializer
      ..moveNext()
      ..expectList();
    Map<String, Object?> namedArgs = {
      for (bool hasNext = deserializer.moveNext();
          hasNext;
          hasNext = deserializer.moveNext())
        deserializer.expectString(): _deserializeArg(deserializer),
    };
    return new Arguments(positionalArgs, namedArgs);
  }

  static Object? _deserializeArg(Deserializer deserializer,
      {bool alreadyMoved = false}) {
    if (!alreadyMoved) deserializer.moveNext();
    _ArgumentKind kind = _ArgumentKind.values[deserializer.expectInt()];
    switch (kind) {
      case _ArgumentKind.nil:
        return null;
      case _ArgumentKind.string:
        deserializer.moveNext();
        return deserializer.expectString();
      case _ArgumentKind.bool:
        deserializer.moveNext();
        return deserializer.expectBool();
      case _ArgumentKind.int:
        deserializer.moveNext();
        return deserializer.expectInt();
      case _ArgumentKind.double:
        deserializer.moveNext();
        return deserializer.expectDouble();
      case _ArgumentKind.list:
        deserializer.moveNext();
        deserializer.expectList();
        return [
          for (bool hasNext = deserializer.moveNext();
              hasNext;
              hasNext = deserializer.moveNext())
            _deserializeArg(deserializer, alreadyMoved: true),
        ];
      case _ArgumentKind.set:
        deserializer.moveNext();
        deserializer.expectList();
        return {
          for (bool hasNext = deserializer.moveNext();
              hasNext;
              hasNext = deserializer.moveNext())
            _deserializeArg(deserializer, alreadyMoved: true),
        };
      case _ArgumentKind.map:
        deserializer.moveNext();
        deserializer.expectList();
        return {
          for (bool hasNext = deserializer.moveNext();
              hasNext;
              hasNext = deserializer.moveNext())
            _deserializeArg(deserializer, alreadyMoved: true):
                _deserializeArg(deserializer),
        };
    }
  }

  void serialize(Serializer serializer) {
    serializer.startList();
    for (Object? arg in positional) {
      _serializeArg(arg, serializer);
    }
    serializer.endList();

    serializer.startList();
    for (MapEntry<String, Object?> arg in named.entries) {
      serializer.addString(arg.key);
      _serializeArg(arg.value, serializer);
    }
    serializer.endList();
  }

  static void _serializeArg(Object? arg, Serializer serializer) {
    if (arg == null) {
      serializer.addInt(_ArgumentKind.nil.index);
    } else if (arg is String) {
      serializer
        ..addInt(_ArgumentKind.string.index)
        ..addString(arg);
    } else if (arg is int) {
      serializer
        ..addInt(_ArgumentKind.int.index)
        ..addInt(arg);
    } else if (arg is double) {
      serializer
        ..addInt(_ArgumentKind.double.index)
        ..addDouble(arg);
    } else if (arg is bool) {
      serializer
        ..addInt(_ArgumentKind.bool.index)
        ..addBool(arg);
    } else if (arg is List) {
      serializer
        ..addInt(_ArgumentKind.list.index)
        ..startList();
      for (Object? item in arg) {
        _serializeArg(item, serializer);
      }
      serializer.endList();
    } else if (arg is Set) {
      serializer
        ..addInt(_ArgumentKind.set.index)
        ..startList();
      for (Object? item in arg) {
        _serializeArg(item, serializer);
      }
      serializer.endList();
    } else if (arg is Map) {
      serializer
        ..addInt(_ArgumentKind.map.index)
        ..startList();
      for (MapEntry<Object?, Object?> entry in arg.entries) {
        _serializeArg(entry.key, serializer);
        _serializeArg(entry.value, serializer);
      }
      serializer.endList();
    } else {
      throw new UnsupportedError('Unsupported argument type $arg');
    }
  }
}

/// A resolved [Identifier], this is used when creating augmentation libraries
/// to qualify identifiers where needed.
class ResolvedIdentifier extends Identifier {
  /// The import URI for the library that defines the member that is referenced
  /// by this identifier.
  ///
  /// If this identifier is an instance member or a built-in type, like
  /// `void`, [uri] is `null`.
  final Uri? uri;

  /// Type of identifier this is (instance, static, top level).
  final IdentifierKind kind;

  /// The unqualified name of this identifier.
  @override
  final String name;

  /// If this is a static member, then the name of the fully qualified scope
  /// surrounding this member. Should not contain a trailing `.`.
  ///
  /// Typically this would just be the name of a type.
  final String? staticScope;

  ResolvedIdentifier({
    required this.kind,
    required this.name,
    required this.staticScope,
    required this.uri,
  });
}

/// The types of identifiers.
enum IdentifierKind {
  instanceMember,
  local, // Parameters, local variables, etc.
  staticInstanceMember,
  topLevelMember,
}

/// An opaque identifier for an instance of a macro class, retrieved by
/// [MacroExecutor.instantiateMacro].
///
/// Used to execute or reload this macro in the future.
abstract class MacroInstanceIdentifier implements Serializable {
  /// Whether or not this instance should run in [phase] on [declarationKind].
  ///
  /// Attempting to execute a macro in a phase it doesn't support, or on a
  /// declaration kind it doesn't support is an error.
  bool shouldExecute(DeclarationKind declarationKind, Phase phase);

  /// Whether or not this macro supports [declarationKind] in any phase.
  bool supportsDeclarationKind(DeclarationKind declarationKind);
}

/// A summary of the results of running a macro in a given phase.
///
/// All modifications are expressed in terms of library augmentation
/// declarations.
abstract class MacroExecutionResult implements Serializable {
  /// Any augmentations that should be applied to a class as a result of
  /// executing a macro, indexed by the name of the class.
  Map<String, Iterable<DeclarationCode>> get classAugmentations;

  /// Any augmentations that should be applied to the library as a result of
  /// executing a macro.
  Iterable<DeclarationCode> get libraryAugmentations;

  /// The names of any new types declared in [augmentations].
  Iterable<String> get newTypeNames;
}

/// Each of the possible types of declarations a macro can be applied to
enum DeclarationKind {
  clazz,
  constructor,
  field,
  function,
  method,
  variable,
}

/// Each of the different macro execution phases.
enum Phase {
  /// Only new types are added in this phase.
  types,

  /// New non-type declarations are added in this phase.
  declarations,

  /// This phase allows augmenting existing declarations.
  definitions,
}

/// Used for serializing and deserializing arguments.
enum _ArgumentKind {
  string,
  bool,
  double,
  int,
  list,
  map,
  set,
  nil,
}
