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

/// Defines the objects used for communication between the macro executor and
/// the isolate or process doing the work of macro loading and execution.
library _fe_analyzer_shared.src.macros.executor_shared.protocol;

import 'package:meta/meta.dart';

import '../executor.dart';
import '../api.dart';
import '../executor/response_impls.dart';
import 'introspection_impls.dart';
import 'remote_instance.dart';
import 'serialization.dart';
import 'serialization_extensions.dart';

/// Base class all requests extend, provides a unique id for each request.
abstract class Request implements Serializable {
  final int id;

  final int serializationZoneId;

  Request({int? id, required this.serializationZoneId})
      : this.id = id ?? _next++;

  /// The [serializationZoneId] is a part of the header and needs to be parsed
  /// before deserializing objects, and then passed in here.
  Request.deserialize(Deserializer deserializer, this.serializationZoneId)
      : id = (deserializer..moveNext()).expectInt();

  /// The [serializationZoneId] needs to be separately serialized before the
  /// rest of the object. This is not done by the instances themselves but by
  /// the macro implementations.
  @mustCallSuper
  void serialize(Serializer serializer) => serializer.addInt(id);

  static int _next = 0;
}

/// A generic response object that contains either a response or an error, and
/// a unique ID.
class Response {
  final Object? response;
  final Object? error;
  final String? stackTrace;
  final int requestId;
  final MessageType responseType;

  Response({
    this.response,
    this.error,
    this.stackTrace,
    required this.requestId,
    required this.responseType,
  })  : assert(response != null || error != null),
        assert(response == null || error == null);
}

/// A serializable [Response], contains the message type as an enum.
class SerializableResponse implements Response, Serializable {
  final Serializable? response;
  final MessageType responseType;
  final String? error;
  final String? stackTrace;
  final int requestId;
  final int serializationZoneId;

  SerializableResponse({
    this.error,
    this.stackTrace,
    required this.requestId,
    this.response,
    required this.responseType,
    required this.serializationZoneId,
  });

  /// You must first parse the [serializationZoneId] yourself, and then
  /// call this function in that zone, and pass the ID.
  factory SerializableResponse.deserialize(
      Deserializer deserializer, int serializationZoneId) {
    deserializer.moveNext();
    MessageType responseType = MessageType.values[deserializer.expectInt()];
    Serializable? response;
    String? error;
    String? stackTrace;
    switch (responseType) {
      case MessageType.error:
        deserializer.moveNext();
        error = deserializer.expectString();
        deserializer.moveNext();
        stackTrace = deserializer.expectNullableString();
        break;
      case MessageType.argumentError:
        deserializer.moveNext();
        error = deserializer.expectString();
        break;
      case MessageType.macroInstanceIdentifier:
        response = new MacroInstanceIdentifierImpl.deserialize(deserializer);
        break;
      case MessageType.macroExecutionResult:
        response = new MacroExecutionResultImpl.deserialize(deserializer);
        break;
      case MessageType.staticType:
      case MessageType.namedStaticType:
        response = RemoteInstance.deserialize(deserializer);
        break;
      case MessageType.boolean:
        response = new BooleanValue.deserialize(deserializer);
        break;
      case MessageType.declarationList:
        response = new DeclarationList.deserialize(deserializer);
        break;
      case MessageType.remoteInstance:
        deserializer.moveNext();
        if (!deserializer.checkNull()) {
          response = deserializer.expectRemoteInstance();
        }
        break;
      default:
        throw new StateError('Unexpected response type $responseType');
    }

    return new SerializableResponse(
        responseType: responseType,
        response: response,
        error: error,
        stackTrace: stackTrace,
        requestId: (deserializer..moveNext()).expectInt(),
        serializationZoneId: serializationZoneId);
  }

  void serialize(Serializer serializer) {
    serializer
      ..addInt(serializationZoneId)
      ..addInt(MessageType.response.index)
      ..addInt(responseType.index);
    switch (responseType) {
      case MessageType.error:
        serializer.addString(error!.toString());
        serializer.addNullableString(stackTrace);
        break;
      case MessageType.argumentError:
        serializer.addString(error!.toString());
        break;
      default:
        response.serializeNullable(serializer);
    }
    serializer.addInt(requestId);
  }
}

class BooleanValue implements Serializable {
  final bool value;

  BooleanValue(this.value);

  BooleanValue.deserialize(Deserializer deserializer)
      : value = (deserializer..moveNext()).expectBool();

  @override
  void serialize(Serializer serializer) => serializer..addBool(value);
}

/// A serialized list of [Declaration]s.
class DeclarationList<T extends DeclarationImpl> implements Serializable {
  final List<T> declarations;

  DeclarationList(this.declarations);

  DeclarationList.deserialize(Deserializer deserializer)
      : declarations = [
          for (bool hasNext = (deserializer
                    ..moveNext()
                    ..expectList())
                  .moveNext();
              hasNext;
              hasNext = deserializer.moveNext())
            deserializer.expectRemoteInstance(),
        ];

  @override
  void serialize(Serializer serializer) {
    serializer.startList();
    for (DeclarationImpl declaration in declarations) {
      declaration.serialize(serializer);
    }
    serializer.endList();
  }
}

/// A request to load a macro in this isolate.
class LoadMacroRequest extends Request {
  final Uri library;
  final String name;

  LoadMacroRequest(this.library, this.name, {required int serializationZoneId})
      : super(serializationZoneId: serializationZoneId);

  LoadMacroRequest.deserialize(
      Deserializer deserializer, int serializationZoneId)
      : library = Uri.parse((deserializer..moveNext()).expectString()),
        name = (deserializer..moveNext()).expectString(),
        super.deserialize(deserializer, serializationZoneId);

  @override
  void serialize(Serializer serializer) {
    serializer
      ..addInt(MessageType.loadMacroRequest.index)
      ..addString(library.toString())
      ..addString(name);
    super.serialize(serializer);
  }
}

/// A request to instantiate a macro instance.
class InstantiateMacroRequest extends Request {
  final Uri library;
  final String name;
  final String constructor;
  final Arguments arguments;

  /// The ID to assign to the identifier, this needs to come from the requesting
  /// side so that it is unique.
  final int instanceId;

  InstantiateMacroRequest(this.library, this.name, this.constructor,
      this.arguments, this.instanceId,
      {required int serializationZoneId})
      : super(serializationZoneId: serializationZoneId);

  InstantiateMacroRequest.deserialize(
      Deserializer deserializer, int serializationZoneId)
      : library = (deserializer..moveNext()).expectUri(),
        name = (deserializer..moveNext()).expectString(),
        constructor = (deserializer..moveNext()).expectString(),
        arguments = new Arguments.deserialize(deserializer),
        instanceId = (deserializer..moveNext()).expectInt(),
        super.deserialize(deserializer, serializationZoneId);

  @override
  void serialize(Serializer serializer) {
    serializer
      ..addInt(MessageType.instantiateMacroRequest.index)
      ..addUri(library)
      ..addString(name)
      ..addString(constructor)
      ..addSerializable(arguments)
      ..addInt(instanceId);
    super.serialize(serializer);
  }
}

/// A request to execute a macro on a particular declaration in the types phase.
class ExecuteTypesPhaseRequest extends Request {
  final MacroInstanceIdentifier macro;
  final DeclarationImpl declaration;
  final RemoteInstanceImpl identifierResolver;

  ExecuteTypesPhaseRequest(
      this.macro, this.declaration, this.identifierResolver,
      {required int serializationZoneId})
      : super(serializationZoneId: serializationZoneId);

  /// When deserializing we have already consumed the message type, so we don't
  /// consume it again.
  ExecuteTypesPhaseRequest.deserialize(
      Deserializer deserializer, int serializationZoneId)
      : macro = new MacroInstanceIdentifierImpl.deserialize(deserializer),
        declaration = RemoteInstance.deserialize(deserializer),
        identifierResolver = RemoteInstance.deserialize(deserializer),
        super.deserialize(deserializer, serializationZoneId);

  void serialize(Serializer serializer) {
    serializer.addInt(MessageType.executeTypesPhaseRequest.index);
    macro.serialize(serializer);
    declaration.serialize(serializer);
    identifierResolver.serialize(serializer);

    super.serialize(serializer);
  }
}

/// A request to execute a macro on a particular declaration in the definition
/// phase.
class ExecuteDeclarationsPhaseRequest extends Request {
  final MacroInstanceIdentifier macro;
  final DeclarationImpl declaration;

  final RemoteInstanceImpl identifierResolver;
  final RemoteInstanceImpl typeResolver;
  final RemoteInstanceImpl classIntrospector;

  ExecuteDeclarationsPhaseRequest(this.macro, this.declaration,
      this.identifierResolver, this.typeResolver, this.classIntrospector,
      {required int serializationZoneId})
      : super(serializationZoneId: serializationZoneId);

  /// When deserializing we have already consumed the message type, so we don't
  /// consume it again.
  ExecuteDeclarationsPhaseRequest.deserialize(
      Deserializer deserializer, int serializationZoneId)
      : macro = new MacroInstanceIdentifierImpl.deserialize(deserializer),
        declaration = RemoteInstance.deserialize(deserializer),
        identifierResolver = RemoteInstance.deserialize(deserializer),
        typeResolver = RemoteInstance.deserialize(deserializer),
        classIntrospector = RemoteInstance.deserialize(deserializer),
        super.deserialize(deserializer, serializationZoneId);

  void serialize(Serializer serializer) {
    serializer.addInt(MessageType.executeDeclarationsPhaseRequest.index);
    macro.serialize(serializer);
    declaration.serialize(serializer);
    identifierResolver.serialize(serializer);
    typeResolver.serialize(serializer);
    classIntrospector.serialize(serializer);

    super.serialize(serializer);
  }
}

/// A request to execute a macro on a particular declaration in the definition
/// phase.
class ExecuteDefinitionsPhaseRequest extends Request {
  final MacroInstanceIdentifier macro;
  final DeclarationImpl declaration;

  final RemoteInstanceImpl identifierResolver;
  final RemoteInstanceImpl typeResolver;
  final RemoteInstanceImpl classIntrospector;
  final RemoteInstanceImpl typeDeclarationResolver;
  final RemoteInstanceImpl typeInferrer;

  ExecuteDefinitionsPhaseRequest(
      this.macro,
      this.declaration,
      this.identifierResolver,
      this.typeResolver,
      this.classIntrospector,
      this.typeDeclarationResolver,
      this.typeInferrer,
      {required int serializationZoneId})
      : super(serializationZoneId: serializationZoneId);

  /// When deserializing we have already consumed the message type, so we don't
  /// consume it again.
  ExecuteDefinitionsPhaseRequest.deserialize(
      Deserializer deserializer, int serializationZoneId)
      : macro = new MacroInstanceIdentifierImpl.deserialize(deserializer),
        declaration = RemoteInstance.deserialize(deserializer),
        identifierResolver = RemoteInstance.deserialize(deserializer),
        typeResolver = RemoteInstance.deserialize(deserializer),
        classIntrospector = RemoteInstance.deserialize(deserializer),
        typeDeclarationResolver = RemoteInstance.deserialize(deserializer),
        typeInferrer = RemoteInstance.deserialize(deserializer),
        super.deserialize(deserializer, serializationZoneId);

  void serialize(Serializer serializer) {
    serializer.addInt(MessageType.executeDefinitionsPhaseRequest.index);
    macro.serialize(serializer);
    declaration.serialize(serializer);
    identifierResolver.serialize(serializer);
    typeResolver.serialize(serializer);
    classIntrospector.serialize(serializer);
    typeDeclarationResolver.serialize(serializer);
    typeInferrer.serialize(serializer);

    super.serialize(serializer);
  }
}

/// A request to create a resolved identifier.
class ResolveIdentifierRequest extends Request {
  final Uri library;
  final String name;

  final RemoteInstanceImpl identifierResolver;

  /// When deserializing we have already consumed the message type, so we don't
  /// consume it again.
  ResolveIdentifierRequest(this.library, this.name, this.identifierResolver,
      {required int serializationZoneId})
      : super(serializationZoneId: serializationZoneId);

  ResolveIdentifierRequest.deserialize(
      Deserializer deserializer, int serializationZoneId)
      : library = Uri.parse((deserializer..moveNext()).expectString()),
        name = (deserializer..moveNext()).expectString(),
        identifierResolver = RemoteInstance.deserialize(deserializer),
        super.deserialize(deserializer, serializationZoneId);

  void serialize(Serializer serializer) {
    serializer
      ..addInt(MessageType.resolveIdentifierRequest.index)
      ..addString(library.toString())
      ..addString(name);
    identifierResolver.serialize(serializer);

    super.serialize(serializer);
  }
}

/// A request to resolve on a type annotation code object
class ResolveTypeRequest extends Request {
  final TypeAnnotationCode typeAnnotationCode;
  final RemoteInstanceImpl typeResolver;

  ResolveTypeRequest(this.typeAnnotationCode, this.typeResolver,
      {required int serializationZoneId})
      : super(serializationZoneId: serializationZoneId);

  /// When deserializing we have already consumed the message type, so we don't
  /// consume it again.
  ResolveTypeRequest.deserialize(
      Deserializer deserializer, int serializationZoneId)
      : typeAnnotationCode = (deserializer..moveNext()).expectCode(),
        typeResolver = RemoteInstance.deserialize(deserializer),
        super.deserialize(deserializer, serializationZoneId);

  void serialize(Serializer serializer) {
    serializer.addInt(MessageType.resolveTypeRequest.index);
    typeAnnotationCode.serialize(serializer);
    typeResolver.serialize(serializer);
    super.serialize(serializer);
  }
}

/// A request to check if a type is exactly another type.
class IsExactlyTypeRequest extends Request {
  final RemoteInstanceImpl leftType;
  final RemoteInstanceImpl rightType;

  IsExactlyTypeRequest(this.leftType, this.rightType,
      {required int serializationZoneId})
      : super(serializationZoneId: serializationZoneId);

  /// When deserializing we have already consumed the message type, so we don't
  /// consume it again.
  IsExactlyTypeRequest.deserialize(
      Deserializer deserializer, int serializationZoneId)
      : leftType = RemoteInstance.deserialize(deserializer),
        rightType = RemoteInstance.deserialize(deserializer),
        super.deserialize(deserializer, serializationZoneId);

  void serialize(Serializer serializer) {
    serializer.addInt(MessageType.isExactlyTypeRequest.index);
    leftType.serialize(serializer);
    rightType.serialize(serializer);
    super.serialize(serializer);
  }
}

/// A request to check if a type is exactly another type.
class IsSubtypeOfRequest extends Request {
  final RemoteInstanceImpl leftType;
  final RemoteInstanceImpl rightType;

  IsSubtypeOfRequest(this.leftType, this.rightType,
      {required int serializationZoneId})
      : super(serializationZoneId: serializationZoneId);

  /// When deserializing we have already consumed the message type, so we don't
  /// consume it again.
  IsSubtypeOfRequest.deserialize(
      Deserializer deserializer, int serializationZoneId)
      : leftType = RemoteInstance.deserialize(deserializer),
        rightType = RemoteInstance.deserialize(deserializer),
        super.deserialize(deserializer, serializationZoneId);

  void serialize(Serializer serializer) {
    serializer.addInt(MessageType.isSubtypeOfRequest.index);
    leftType.serialize(serializer);
    rightType.serialize(serializer);
    super.serialize(serializer);
  }
}

/// A general request class for all requests coming from methods on the
/// [ClassIntrospector] interface.
class ClassIntrospectionRequest extends Request {
  final ClassDeclarationImpl classDeclaration;
  final RemoteInstanceImpl classIntrospector;
  final MessageType requestKind;

  ClassIntrospectionRequest(
      this.classDeclaration, this.classIntrospector, this.requestKind,
      {required int serializationZoneId})
      : super(serializationZoneId: serializationZoneId);

  /// When deserializing we have already consumed the message type, so we don't
  /// consume it again and it should instead be passed in here.
  ClassIntrospectionRequest.deserialize(
      Deserializer deserializer, this.requestKind, int serializationZoneId)
      : classDeclaration = RemoteInstance.deserialize(deserializer),
        classIntrospector = RemoteInstance.deserialize(deserializer),
        super.deserialize(deserializer, serializationZoneId);

  @override
  void serialize(Serializer serializer) {
    serializer.addInt(requestKind.index);
    classDeclaration.serialize(serializer);
    classIntrospector.serialize(serializer);
    super.serialize(serializer);
  }
}

/// A request to get a [TypeDeclaration] for a [StaticType].
class DeclarationOfRequest extends Request {
  final IdentifierImpl identifier;
  final RemoteInstanceImpl typeDeclarationResolver;

  DeclarationOfRequest(this.identifier, this.typeDeclarationResolver,
      {required int serializationZoneId})
      : super(serializationZoneId: serializationZoneId);

  /// When deserializing we have already consumed the message type, so we don't
  /// consume it again.
  DeclarationOfRequest.deserialize(
      Deserializer deserializer, int serializationZoneId)
      : identifier = RemoteInstance.deserialize(deserializer),
        typeDeclarationResolver = RemoteInstance.deserialize(deserializer),
        super.deserialize(deserializer, serializationZoneId);

  @override
  void serialize(Serializer serializer) {
    serializer.addInt(MessageType.declarationOfRequest.index);
    identifier.serialize(serializer);
    typeDeclarationResolver.serialize(serializer);
    super.serialize(serializer);
  }
}

/// A request to get an inferred [TypeAnnotation] for an
/// [OmittedTypeAnnotation].
class InferTypeRequest extends Request {
  final OmittedTypeAnnotationImpl omittedType;
  final RemoteInstanceImpl typeInferrer;

  InferTypeRequest(this.omittedType, this.typeInferrer,
      {required int serializationZoneId})
      : super(serializationZoneId: serializationZoneId);

  /// When deserializing we have already consumed the message type, so we don't
  /// consume it again.
  InferTypeRequest.deserialize(
      Deserializer deserializer, int serializationZoneId)
      : omittedType = RemoteInstance.deserialize(deserializer),
        typeInferrer = RemoteInstance.deserialize(deserializer),
        super.deserialize(deserializer, serializationZoneId);

  @override
  void serialize(Serializer serializer) {
    serializer.addInt(MessageType.inferTypeRequest.index);
    omittedType.serialize(serializer);
    typeInferrer.serialize(serializer);
    super.serialize(serializer);
  }
}

/// Client side implementation of an [IdentifierResolver], which creates a
/// [ResolveIdentifierRequest] and passes it to a given [_sendRequest] function
/// which can return the [Response].
class ClientIdentifierResolver implements IdentifierResolver {
  /// The actual remote instance of this type resolver.
  final RemoteInstanceImpl remoteInstance;

  /// The ID of the zone in which to find the original type resolver.
  final int serializationZoneId;

  /// A function that can send a request and return a response using an
  /// arbitrary communication channel.
  final Future<Response> Function(Request request) _sendRequest;

  ClientIdentifierResolver(this._sendRequest,
      {required this.remoteInstance, required this.serializationZoneId});

  @override
  Future<Identifier> resolveIdentifier(Uri library, String name) async {
    ResolveIdentifierRequest request = new ResolveIdentifierRequest(
        library, name, remoteInstance,
        serializationZoneId: serializationZoneId);
    return _handleResponse(await _sendRequest(request));
  }
}

/// Client side implementation of a [TypeResolver], which creates a
/// [ResolveTypeRequest] and passes it to a given [sendRequest] function which
/// can return the [Response].
class ClientTypeResolver implements TypeResolver {
  /// The actual remote instance of this type resolver.
  final RemoteInstanceImpl remoteInstance;

  /// The ID of the zone in which to find the original type resolver.
  final int serializationZoneId;

  /// A function that can send a request and return a response using an
  /// arbitrary communication channel.
  final Future<Response> Function(Request request) _sendRequest;

  ClientTypeResolver(this._sendRequest,
      {required this.remoteInstance, required this.serializationZoneId});

  @override
  Future<StaticType> resolve(TypeAnnotationCode typeAnnotation) async {
    ResolveTypeRequest request = new ResolveTypeRequest(
        typeAnnotation, remoteInstance,
        serializationZoneId: serializationZoneId);
    RemoteInstanceImpl remoteType =
        _handleResponse(await _sendRequest(request));
    switch (remoteType.kind) {
      case RemoteInstanceKind.namedStaticType:
        return new ClientNamedStaticTypeImpl(_sendRequest,
            remoteInstance: remoteType,
            serializationZoneId: serializationZoneId);
      case RemoteInstanceKind.staticType:
        return new ClientStaticTypeImpl(_sendRequest,
            remoteInstance: remoteType,
            serializationZoneId: serializationZoneId);
      default:
        throw new StateError(
            'Expected either a StaticType or NamedStaticType but got '
            '${remoteType.kind}');
    }
  }
}

class ClientStaticTypeImpl implements StaticType {
  /// The actual remote instance of this static type.
  final RemoteInstanceImpl remoteInstance;

  final int serializationZoneId;

  /// A function that can send a request and return a response using an
  /// arbitrary communication channel.
  final Future<Response> Function(Request request) sendRequest;

  ClientStaticTypeImpl(this.sendRequest,
      {required this.remoteInstance, required this.serializationZoneId});

  @override
  Future<bool> isExactly(ClientStaticTypeImpl other) async {
    IsExactlyTypeRequest request = new IsExactlyTypeRequest(
        this.remoteInstance, other.remoteInstance,
        serializationZoneId: serializationZoneId);
    return _handleResponse<BooleanValue>(await sendRequest(request)).value;
  }

  @override
  Future<bool> isSubtypeOf(ClientStaticTypeImpl other) async {
    IsSubtypeOfRequest request = new IsSubtypeOfRequest(
        remoteInstance, other.remoteInstance,
        serializationZoneId: serializationZoneId);
    return _handleResponse<BooleanValue>(await sendRequest(request)).value;
  }
}

/// Named variant of the [ClientStaticTypeImpl].
class ClientNamedStaticTypeImpl extends ClientStaticTypeImpl
    implements NamedStaticType {
  ClientNamedStaticTypeImpl(
      Future<Response> Function(Request request) sendRequest,
      {required RemoteInstanceImpl remoteInstance,
      required int serializationZoneId})
      : super(sendRequest,
            remoteInstance: remoteInstance,
            serializationZoneId: serializationZoneId);
}

/// Client side implementation of the [ClientClassIntrospector], converts all
/// invocations into remote RPC calls.
class ClientClassIntrospector implements ClassIntrospector {
  /// The actual remote instance of this class introspector.
  final RemoteInstanceImpl remoteInstance;

  /// The ID of the zone in which to find the original type resolver.
  final int serializationZoneId;

  /// A function that can send a request and return a response using an
  /// arbitrary communication channel.
  final Future<Response> Function(Request request) sendRequest;

  ClientClassIntrospector(this.sendRequest,
      {required this.remoteInstance, required this.serializationZoneId});

  @override
  Future<List<ConstructorDeclaration>> constructorsOf(
      ClassDeclarationImpl clazz) async {
    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
        clazz, remoteInstance, MessageType.constructorsOfRequest,
        serializationZoneId: serializationZoneId);
    return _handleResponse<DeclarationList>(await sendRequest(request))
        .declarations
        // TODO: Refactor so we can remove this cast
        .cast();
  }

  @override
  Future<List<FieldDeclaration>> fieldsOf(ClassDeclarationImpl clazz) async {
    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
        clazz, remoteInstance, MessageType.fieldsOfRequest,
        serializationZoneId: serializationZoneId);
    return _handleResponse<DeclarationList>(await sendRequest(request))
        .declarations
        // TODO: Refactor so we can remove this cast
        .cast();
  }

  @override
  Future<List<ClassDeclaration>> interfacesOf(
      ClassDeclarationImpl clazz) async {
    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
        clazz, remoteInstance, MessageType.interfacesOfRequest,
        serializationZoneId: serializationZoneId);
    return _handleResponse<DeclarationList>(await sendRequest(request))
        .declarations
        // TODO: Refactor so we can remove this cast
        .cast();
  }

  @override
  Future<List<MethodDeclaration>> methodsOf(ClassDeclarationImpl clazz) async {
    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
        clazz, remoteInstance, MessageType.methodsOfRequest,
        serializationZoneId: serializationZoneId);
    return _handleResponse<DeclarationList>(await sendRequest(request))
        .declarations
        // TODO: Refactor so we can remove this cast
        .cast();
  }

  @override
  Future<List<ClassDeclaration>> mixinsOf(ClassDeclarationImpl clazz) async {
    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
        clazz, remoteInstance, MessageType.mixinsOfRequest,
        serializationZoneId: serializationZoneId);
    return _handleResponse<DeclarationList>(await sendRequest(request))
        .declarations
        // TODO: Refactor so we can remove this cast
        .cast();
  }

  @override
  Future<ClassDeclaration?> superclassOf(ClassDeclarationImpl clazz) async {
    ClassIntrospectionRequest request = new ClassIntrospectionRequest(
        clazz, remoteInstance, MessageType.superclassOfRequest,
        serializationZoneId: serializationZoneId);
    return _handleResponse<ClassDeclaration?>(await sendRequest(request));
  }
}

/// Client side implementation of a [TypeDeclarationResolver], converts all
/// invocations into remote procedure calls.
class ClientTypeDeclarationResolver implements TypeDeclarationResolver {
  /// The actual remote instance of this type resolver.
  final RemoteInstanceImpl remoteInstance;

  /// The ID of the zone in which to find the original type resolver.
  final int serializationZoneId;

  /// A function that can send a request and return a response using an
  /// arbitrary communication channel.
  final Future<Response> Function(Request request) sendRequest;

  ClientTypeDeclarationResolver(this.sendRequest,
      {required this.remoteInstance, required this.serializationZoneId});

  @override
  Future<TypeDeclaration> declarationOf(IdentifierImpl identifier) async {
    DeclarationOfRequest request = new DeclarationOfRequest(
        identifier, remoteInstance,
        serializationZoneId: serializationZoneId);
    return _handleResponse<TypeDeclaration>(await sendRequest(request));
  }
}

/// Client side implementation of a [TypeInferrer], converts all
/// invocations into remote procedure calls.
class ClientTypeInferrer implements TypeInferrer {
  /// The actual remote instance of this type resolver.
  final RemoteInstanceImpl remoteInstance;

  /// The ID of the zone in which to find the original type resolver.
  final int serializationZoneId;

  /// A function that can send a request and return a response using an
  /// arbitrary communication channel.
  final Future<Response> Function(Request request) sendRequest;

  ClientTypeInferrer(this.sendRequest,
      {required this.remoteInstance, required this.serializationZoneId});

  @override
  Future<TypeAnnotation> inferType(
      OmittedTypeAnnotationImpl omittedType) async {
    InferTypeRequest request = new InferTypeRequest(omittedType, remoteInstance,
        serializationZoneId: serializationZoneId);
    return _handleResponse<TypeAnnotation>(await sendRequest(request));
  }
}

/// An exception that occurred remotely, the exception object and stack trace
/// are serialized as [String]s and both included in the [toString] output.
class RemoteException implements Exception {
  final String error;
  final String? stackTrace;

  RemoteException(this.error, [this.stackTrace]);

  String toString() =>
      'RemoteException: $error${stackTrace == null ? '' : '\n\n$stackTrace'}';
}

/// Either returns the actual response from [response], casted to [T], or throws
/// a [RemoteException] with the given error and stack trace.
T _handleResponse<T>(Response response) {
  if (response.responseType == MessageType.error) {
    throw new RemoteException(response.error!.toString(), response.stackTrace);
  } else if (response.responseType == MessageType.argumentError) {
    throw new ArgumentError(response.error!.toString());
  }

  return response.response as T;
}

enum MessageType {
  argumentError,
  boolean,
  constructorsOfRequest,
  declarationOfRequest,
  declarationList,
  fieldsOfRequest,
  interfacesOfRequest,
  methodsOfRequest,
  mixinsOfRequest,
  superclassOfRequest,
  error,
  executeDeclarationsPhaseRequest,
  executeDefinitionsPhaseRequest,
  executeTypesPhaseRequest,
  instantiateMacroRequest,
  resolveIdentifierRequest,
  resolveTypeRequest,
  inferTypeRequest,
  isExactlyTypeRequest,
  isSubtypeOfRequest,
  loadMacroRequest,
  remoteInstance,
  macroInstanceIdentifier,
  macroExecutionResult,
  namedStaticType,
  response,
  staticType,
}
