// 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 'dart:async';
import 'dart:isolate';
import 'dart:mirrors';

import '../executor_shared/builder_impls.dart';
import '../executor_shared/introspection_impls.dart';
import '../executor_shared/response_impls.dart';
import '../executor_shared/protocol.dart';
import '../api.dart';

/// Spawns a new isolate for loading and executing macros.
void spawn(SendPort sendPort) {
  ReceivePort receivePort = new ReceivePort();
  sendPort.send(receivePort.sendPort);
  receivePort.listen((message) async {
    Response response;
    if (message is LoadMacroRequest) {
      response = await _loadMacro(message);
    } else if (message is InstantiateMacroRequest) {
      response = await _instantiateMacro(message);
    } else if (message is ExecuteDefinitionsPhaseRequest) {
      response = await _executeDefinitionsPhase(message);
    } else {
      throw new StateError('Unrecognized event type $message');
    }
    sendPort.send(response);
  });
}

/// Maps macro identifiers to class mirrors.
final _macroClasses = <MacroClassIdentifierImpl, ClassMirror>{};

/// Handles [LoadMacroRequest]s.
Future<Response> _loadMacro(LoadMacroRequest request) async {
  try {
    MacroClassIdentifierImpl identifier =
        new MacroClassIdentifierImpl(request.library, request.name);
    if (_macroClasses.containsKey(identifier)) {
      throw new UnsupportedError(
          'Reloading macros is not supported by this implementation');
    }
    LibraryMirror libMirror =
        await currentMirrorSystem().isolate.loadUri(request.library);
    ClassMirror macroClass =
        libMirror.declarations[new Symbol(request.name)] as ClassMirror;
    _macroClasses[identifier] = macroClass;
    return new Response(
        response: identifier,
        requestId: request.id,
        responseType: MessageType.macroClassIdentifier);
  } catch (e) {
    return new Response(
        error: e, requestId: request.id, responseType: MessageType.error);
  }
}

/// Maps macro instance identifiers to instances.
final _macroInstances = <MacroInstanceIdentifierImpl, Macro>{};

/// Handles [InstantiateMacroRequest]s.
Future<Response> _instantiateMacro(InstantiateMacroRequest request) async {
  try {
    ClassMirror? clazz = _macroClasses[request.macroClass];
    if (clazz == null) {
      throw new ArgumentError('Unrecognized macro class ${request.macroClass}');
    }
    Macro instance = clazz.newInstance(
        new Symbol(request.constructorName), request.arguments.positional, {
      for (MapEntry<String, Object?> entry in request.arguments.named.entries)
        new Symbol(entry.key): entry.value,
    }).reflectee as Macro;
    MacroInstanceIdentifierImpl identifier = new MacroInstanceIdentifierImpl();
    _macroInstances[identifier] = instance;
    return new Response(
        response: identifier,
        requestId: request.id,
        responseType: MessageType.macroInstanceIdentifier);
  } catch (e) {
    return new Response(
        error: e, requestId: request.id, responseType: MessageType.error);
  }
}

Future<Response> _executeDefinitionsPhase(
    ExecuteDefinitionsPhaseRequest request) async {
  try {
    Macro? instance = _macroInstances[request.macro];
    if (instance == null) {
      throw new StateError('Unrecognized macro instance ${request.macro}\n'
          'Known instances: $_macroInstances)');
    }
    DeclarationImpl declaration = request.declaration;
    if (instance is FunctionDefinitionMacro &&
        declaration is FunctionDeclarationImpl) {
      FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
          declaration,
          request.classIntrospector.instance as ClassIntrospector,
          request.typeResolver.instance as TypeResolver,
          request.typeDeclarationResolver.instance as TypeDeclarationResolver);
      await instance.buildDefinitionForFunction(declaration, builder);
      return new Response(
          response: builder.result,
          requestId: request.id,
          responseType: MessageType.macroExecutionResult);
    } else if (instance is MethodDefinitionMacro &&
        declaration is MethodDeclarationImpl) {
      FunctionDefinitionBuilderImpl builder = new FunctionDefinitionBuilderImpl(
          declaration,
          request.classIntrospector.instance as ClassIntrospector,
          request.typeResolver.instance as TypeResolver,
          request.typeDeclarationResolver.instance as TypeDeclarationResolver);
      await instance.buildDefinitionForMethod(declaration, builder);
      return new SerializableResponse(
          responseType: MessageType.macroExecutionResult,
          response: builder.result,
          requestId: request.id,
          serializationZoneId: request.serializationZoneId);
    } else {
      throw new UnsupportedError(
          'Only Method and Function Definition Macros are supported currently');
    }
  } catch (e) {
    return new Response(
        error: e, requestId: request.id, responseType: MessageType.error);
  }
}
