// 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), // ignore: unnecessary_null_comparison
       assert(codec != null); // ignore: unnecessary_null_comparison

  /// 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) {
    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); // ignore: unnecessary_null_comparison

  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);
  }
}
