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

import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer_plugin/channel/channel.dart';
import 'package:analyzer_plugin/protocol/protocol.dart';
import 'package:analyzer_plugin/protocol/protocol_generated.dart';

/// The type of the function used to run a built-in plugin in an isolate.
typedef EntryPoint = void Function(SendPort sendPort);

/// A communication channel appropriate for built-in plugins.
class BuiltInServerIsolateChannel extends ServerIsolateChannel {
  /// The entry point
  final EntryPoint entryPoint;

  @override
  final String pluginId;

  /// Initialize a newly created channel to communicate with an isolate running
  /// the given [entryPoint].
  BuiltInServerIsolateChannel(
    this.entryPoint,
    this.pluginId,
    InstrumentationService instrumentationService,
  ) : super._(instrumentationService);

  @override
  Future<Isolate> _spawnIsolate() {
    return Isolate.spawn(
      (message) => entryPoint(message as SendPort),
      _receivePort?.sendPort,
      onError: _errorPort?.sendPort,
      onExit: _exitPort?.sendPort,
    );
  }
}

/// A communication channel appropriate for discovered plugins.
class DiscoveredServerIsolateChannel extends ServerIsolateChannel {
  /// The URI for the Dart file that will be run in the isolate that this
  /// channel communicates with.
  final Uri pluginUri;

  /// The URI for the '.packages' file that will control how 'package:' URIs are
  /// resolved.
  final Uri packagesUri;

  /// Initialize a newly created channel to communicate with an isolate running
  /// the code at the given [uri].
  DiscoveredServerIsolateChannel(
    this.pluginUri,
    this.packagesUri,
    InstrumentationService instrumentationService,
  ) : super._(instrumentationService);

  @override
  String get pluginId => pluginUri.toString();

  @override
  Future<Isolate> _spawnIsolate() {
    return Isolate.spawnUri(
      pluginUri,
      <String>[],
      _receivePort?.sendPort,
      onError: _errorPort?.sendPort,
      onExit: _exitPort?.sendPort,
      packageConfig: packagesUri,
    );
  }
}

/// The object that allows a [ServerPlugin] to receive [Request]s and to return
/// both [Response]s and [Notification]s. It communicates with the analysis
/// server by passing data to the server's main isolate.
class PluginIsolateChannel implements PluginCommunicationChannel {
  /// The port used to send notifications and responses to the server.
  final SendPort _sendPort;

  /// The port used to receive requests from the server.
  late final ReceivePort _receivePort;

  /// The subscription that needs to be cancelled when the channel is closed.
  StreamSubscription? _subscription;

  /// Initialize a newly created channel to communicate with the server.
  PluginIsolateChannel(this._sendPort) {
    _receivePort = ReceivePort();
    _sendPort.send(_receivePort.sendPort);
  }

  @override
  void close() {
    _receivePort.close();
    _subscription?.cancel();
    _subscription = null;
  }

  @override
  void listen(
    void Function(Request request) onRequest, {
    Function? onError,
    void Function()? onDone,
  }) {
    void onData(data) {
      var requestMap = data as Map<String, Object>;
      var request = Request.fromJson(requestMap);
      onRequest(request);
    }

    if (_subscription != null) {
      throw StateError('Only one listener is allowed per channel');
    }
    // Note: The documentation for [ReceivePort.listen] indicates that
    // `onError` and `cancelOnError` are always ignored, "since a ReceivePort
    // will never receive an error." It is potentially confusing to pass them
    // here, as if they had an effect. Consider removing.
    _subscription = _receivePort.listen(
      onData,
      onError: onError,
      onDone: onDone,
      cancelOnError: false,
    );
  }

  @override
  void sendNotification(Notification notification) {
    var json = notification.toJson();
    _sendPort.send(json);
  }

  @override
  void sendResponse(Response response) {
    var json = response.toJson();
    _sendPort.send(json);
  }
}

/// A communication channel that allows an analysis server to send [Request]s
/// to, and to receive both [Response]s and [Notification]s from, a plugin.
abstract class ServerIsolateChannel implements ServerCommunicationChannel {
  /// The instrumentation service that is being used by the analysis server.
  final InstrumentationService instrumentationService;

  /// The isolate in which the plugin is running, or `null` if the plugin has
  /// not yet been started by invoking [listen].
  Isolate? _isolate;

  /// The port used to send requests to the plugin, or `null` if the plugin has
  /// not yet been started by invoking [listen].
  SendPort? _sendPort;

  /// The port used to receive responses and notifications from the plugin.
  ReceivePort? _receivePort;

  /// The port used to receive unhandled exceptions thrown in the plugin.
  ReceivePort? _errorPort;

  /// The port used to receive notification when the plugin isolate has exited.
  ReceivePort? _exitPort;

  /// Return a communication channel appropriate for communicating with a
  /// built-in plugin.
  factory ServerIsolateChannel.builtIn(
    EntryPoint entryPoint,
    String pluginId,
    InstrumentationService instrumentationService,
  ) = BuiltInServerIsolateChannel;

  /// Return a communication channel appropriate for communicating with a
  /// discovered plugin.
  factory ServerIsolateChannel.discovered(
    Uri pluginUri,
    Uri packagesUri,
    InstrumentationService instrumentationService,
  ) = DiscoveredServerIsolateChannel;

  /// Initialize a newly created channel.
  ServerIsolateChannel._(this.instrumentationService);

  /// Return the id of the plugin running in the isolate, used to identify the
  /// plugin to the instrumentation service.
  String get pluginId;

  @override
  void close() {
    _receivePort?.close();
    _errorPort?.close();
    _exitPort?.close();
    _isolate = null;
  }

  @override
  void kill() {
    _isolate?.kill(priority: Isolate.immediate);
  }

  @override
  Future<void> listen(
    void Function(Response response) onResponse,
    void Function(Notification notification) onNotification, {
    void Function(dynamic error)? onError,
    void Function()? onDone,
  }) async {
    if (_isolate != null) {
      throw StateError('Cannot listen to the same channel more than once.');
    }

    var receivePort = ReceivePort();
    _receivePort = receivePort;

    if (onError != null) {
      var errorPort = ReceivePort();
      _errorPort = errorPort;
      errorPort.listen((error) {
        onError(error);
      });
    }

    if (onDone != null) {
      var exitPort = ReceivePort();
      _exitPort = exitPort;
      exitPort.listen((_) {
        onDone();
      });
    }

    try {
      _isolate = await _spawnIsolate();
    } catch (exception, stackTrace) {
      instrumentationService.logPluginError(
        PluginData(pluginId, null, null),
        RequestErrorCode.PLUGIN_ERROR.toString(),
        exception.toString(),
        stackTrace.toString(),
      );
      if (onError != null) {
        onError([exception.toString(), stackTrace.toString()]);
      }
      if (onDone != null) {
        onDone();
      }
      close();
      return;
    }

    var channelReady = Completer<void>();
    receivePort.listen((dynamic input) {
      if (input is SendPort) {
        _sendPort = input;
        channelReady.complete(null);
      } else if (input is Map<String, Object?>) {
        if (input.containsKey('id')) {
          var encodedInput = json.encode(input);
          instrumentationService.logPluginResponse(pluginId, encodedInput);
          onResponse(Response.fromJson(input));
        } else if (input.containsKey('event')) {
          var encodedInput = json.encode(input);
          instrumentationService.logPluginNotification(pluginId, encodedInput);
          onNotification(Notification.fromJson(input));
        }
      }
    });

    return channelReady.future;
  }

  @override
  void sendRequest(Request request) {
    var sendPort = _sendPort;
    if (sendPort != null) {
      var jsonData = request.toJson();
      var encodedRequest = json.encode(jsonData);
      instrumentationService.logPluginRequest(pluginId, encodedRequest);
      sendPort.send(jsonData);
    }
  }

  /// Spawn the isolate in which the plugin is running.
  Future<Isolate> _spawnIsolate();
}
