// 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 'isolate_mirrors_impl.dart';
import '../executor_shared/introspection_impls.dart';
import '../executor_shared/protocol.dart';
import '../executor_shared/remote_instance.dart';
import '../executor.dart';
import '../api.dart';

/// Returns an instance of [_IsolateMirrorMacroExecutor].
///
/// This is the only public api exposed by this library.
Future<MacroExecutor> start() => _IsolateMirrorMacroExecutor.start();

/// A [MacroExecutor] implementation which relies on [IsolateMirror.loadUri]
/// in order to load macros libraries.
///
/// All actual work happens in a separate [Isolate], and this class serves as
/// a bridge between that isolate and the language frontends.
class _IsolateMirrorMacroExecutor implements MacroExecutor {
  /// The actual isolate doing macro loading and execution.
  final Isolate _macroIsolate;

  /// The channel used to send requests to the [_macroIsolate].
  final SendPort _sendPort;

  /// The stream of responses from the [_macroIsolate].
  final Stream<Response> _responseStream;

  /// A map of response completers by request id.
  final _responseCompleters = <int, Completer<Response>>{};

  /// A function that should be invoked when shutting down this executor
  /// to perform any necessary cleanup.
  final void Function() _onClose;

  _IsolateMirrorMacroExecutor._(
      this._macroIsolate, this._sendPort, this._responseStream, this._onClose) {
    _responseStream.listen((event) {
      Completer<Response>? completer =
          _responseCompleters.remove(event.requestId);
      if (completer == null) {
        throw new StateError(
            'Got a response for an unrecognized request id ${event.requestId}');
      }
      completer.complete(event);
    });
  }

  /// Initialize an [IsolateMirrorMacroExecutor] and return it once ready.
  ///
  /// Spawns the macro isolate and sets up a communication channel.
  static Future<MacroExecutor> start() async {
    ReceivePort receivePort = new ReceivePort();
    Completer<SendPort> sendPortCompleter = new Completer<SendPort>();
    StreamController<Response> responseStreamController =
        new StreamController<Response>(sync: true);
    receivePort.listen((message) {
      if (!sendPortCompleter.isCompleted) {
        sendPortCompleter.complete(message as SendPort);
      } else {
        responseStreamController.add(message as Response);
      }
    }).onDone(responseStreamController.close);
    Isolate macroIsolate = await Isolate.spawn(spawn, receivePort.sendPort);

    return new _IsolateMirrorMacroExecutor._(
        macroIsolate,
        await sendPortCompleter.future,
        responseStreamController.stream,
        receivePort.close);
  }

  @override
  Future<String> buildAugmentationLibrary(
      Iterable<MacroExecutionResult> macroResults) {
    // TODO: implement buildAugmentationLibrary
    throw new UnimplementedError();
  }

  @override
  void close() {
    _onClose();
    _macroIsolate.kill();
  }

  @override
  Future<MacroExecutionResult> executeDeclarationsPhase(
      MacroInstanceIdentifier macro,
      Declaration declaration,
      TypeResolver typeResolver,
      ClassIntrospector classIntrospector) {
    // TODO: implement executeDeclarationsPhase
    throw new UnimplementedError();
  }

  @override
  Future<MacroExecutionResult> executeDefinitionsPhase(
          MacroInstanceIdentifier macro,
          DeclarationImpl declaration,
          TypeResolver typeResolver,
          ClassIntrospector classIntrospector,
          TypeDeclarationResolver typeDeclarationResolver) =>
      _sendRequest(new ExecuteDefinitionsPhaseRequest(
          macro,
          declaration,
          new RemoteInstanceImpl(
              instance: typeResolver, id: RemoteInstance.uniqueId),
          new RemoteInstanceImpl(
              instance: classIntrospector, id: RemoteInstance.uniqueId),
          new RemoteInstanceImpl(
              instance: typeDeclarationResolver, id: RemoteInstance.uniqueId),
          // Serialization zones are not necessary in this executor.
          serializationZoneId: -1));

  @override
  Future<MacroExecutionResult> executeTypesPhase(
      MacroInstanceIdentifier macro, Declaration declaration) {
    // TODO: implement executeTypesPhase
    throw new UnimplementedError();
  }

  @override
  Future<MacroInstanceIdentifier> instantiateMacro(
          MacroClassIdentifier macroClass,
          String constructor,
          Arguments arguments) =>
      _sendRequest(
          new InstantiateMacroRequest(macroClass, constructor, arguments,
              // Serialization zones are not necessary in this executor.
              serializationZoneId: -1));

  @override
  Future<MacroClassIdentifier> loadMacro(Uri library, String name,
      {Uri? precompiledKernelUri}) {
    if (precompiledKernelUri != null) {
      // TODO: Implement support?
      throw new UnsupportedError(
          'The IsolateMirrorsExecutor does not support precompiled dill files');
    }
    return _sendRequest(new LoadMacroRequest(library, name,
        // Serialization zones are not necessary in this executor.
        serializationZoneId: -1));
  }

  /// Sends a request and returns the response, casting it to the expected
  /// type.
  Future<T> _sendRequest<T>(Request request) async {
    _sendPort.send(request);
    Completer<Response> completer = new Completer<Response>();
    _responseCompleters[request.id] = completer;
    Response response = await completer.future;
    T? result = response.response as T?;
    if (result != null) return result;
    throw response.error!;
  }
}
