// Copyright 2014 The Flutter Authors. 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 'package:flutter/services.dart';

import 'plugin_registry.dart';

/// A named channel for sending events to the framework-side using streams.
///
/// This is the platform-side equivalent of [EventChannel]. Whereas
/// [EventChannel] receives a stream of events from platform plugins, this
/// channel sends a stream of events to the handler listening on the
/// framework-side.
///
/// The channel [name] must not be null. If no [codec] is provided, then
/// [StandardMethodCodec] is used. If no [binaryMessenger] is provided, then
/// [pluginBinaryMessenger], which sends messages to the framework-side,
/// is used.
///
/// Channels created using this class implement two methods for
/// subscribing to the event stream. The methods use the encoding of
/// the specified [codec].
///
/// The first method is `listen`. When called, it begins forwarding
/// messages to the framework side when they are added to the
/// `controller`. This triggers the [StreamController.onListen] callback
/// on the `controller`.
///
/// The other method is `cancel`. When called, it stops forwarding
/// events to the framework. This triggers the [StreamController.onCancel]
/// callback on the `controller`.
///
/// Events added to the `controller` when the framework is not
/// subscribed are silently discarded.
class PluginEventChannel<T> {
  /// Creates a new plugin event channel.
  ///
  /// The [name] and [codec] arguments must not be null.
  const PluginEventChannel(
    this.name, [
    this.codec = const StandardMethodCodec(),
    this.binaryMessenger,
  ]) : assert(name != null),
       assert(codec != null);

  /// The logical channel on which communication happens.
  ///
  /// This must not be null.
  final String name;

  /// The message codec used by this channel.
  ///
  /// This must not be null. This defaults to [StandardMethodCodec].
  final MethodCodec codec;

  /// The messenger used by this channel to send platform messages.
  ///
  /// When this is null, the [pluginBinaryMessenger] is used instead,
  /// which sends messages from the platform-side to the
  /// framework-side.
  final BinaryMessenger? binaryMessenger;

  /// Use [setController] instead.
  ///
  /// This setter is deprecated because it has no corresponding getter,
  /// and providing a getter would require making this class non-const.
  @Deprecated(
    'Replace calls to the "controller" setter with calls to the "setController" method. '
    'This feature was deprecated after v1.23.0-7.0.pre.'
  )
  set controller(StreamController<T> controller) { // ignore: avoid_setters_without_getters
    setController(controller);
  }

  /// Changes the stream controller for this event channel.
  ///
  /// Setting the controller to null disconnects from the channel (setting
  /// the message handler on the [binaryMessenger] to null).
  void setController(StreamController<T>? controller) {
    final BinaryMessenger messenger = binaryMessenger ?? pluginBinaryMessenger;
    if (controller == null) {
      messenger.setMessageHandler(name, null);
    } else {
      // The handler object is kept alive via its handle() method
      // keeping a reference to itself. Ideally we would keep a
      // reference to it so that there was a clear ownership model,
      // but that would require making this class non-const. Having
      // this class be const is convenient since it allows references
      // to be obtained by using the constructor rather than having
      // to literally pass references around.
      final _EventChannelHandler<T> handler = _EventChannelHandler<T>(
        name,
        codec,
        controller,
        messenger,
      );
      messenger.setMessageHandler(name, handler.handle);
    }
  }
}

class _EventChannelHandler<T> {
  _EventChannelHandler(
    this.name,
    this.codec,
    this.controller,
    this.messenger,
  ) : assert(messenger != null);

  final String name;
  final MethodCodec codec;
  final StreamController<T> controller;
  final BinaryMessenger messenger;

  StreamSubscription<T>? subscription;

  Future<ByteData>? handle(ByteData? message) {
    final MethodCall call = codec.decodeMethodCall(message);
    switch (call.method) {
      case 'listen':
        assert(call.arguments == null);
        return _listen();
      case 'cancel':
        assert(call.arguments == null);
        return _cancel();
    }
    return null;
  }

  Future<ByteData> _listen() async {
    // Cancel any existing subscription.
    await subscription?.cancel();
    subscription = controller.stream.listen((dynamic event) {
      messenger.send(name, codec.encodeSuccessEnvelope(event));
    }, onError: (dynamic error) {
      messenger.send(name, codec.encodeErrorEnvelope(code: 'error', message: '$error'));
    });
    return codec.encodeSuccessEnvelope(null);
  }

  Future<ByteData> _cancel() async {
    if (subscription == null) {
      return codec.encodeErrorEnvelope(
        code: 'error',
        message: 'No active subscription to cancel.',
      );
    }
    await subscription!.cancel();
    subscription = null;
    return codec.encodeSuccessEnvelope(null);
  }
}
