// 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 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';

/// A registrar for Flutter plugins implemented in Dart.
///
/// Plugins for the web platform are implemented in Dart and are
/// registered with this class by code generated by the `flutter` tool
/// when compiling the application.
///
/// This class implements [BinaryMessenger] to route messages from the
/// framework to registered plugins.
///
/// Use this [BinaryMessenger] when creating platform channels in order for
/// them to receive messages from the platform side. For example:
///
/// ```dart
/// class MyPlugin {
///   static void registerWith(Registrar registrar) {
///     final MethodChannel channel = MethodChannel(
///       'com.my_plugin/my_plugin',
///       const StandardMethodCodec(),
///       registrar, // the registrar is used as the BinaryMessenger
///     );
///     final MyPlugin instance = MyPlugin();
///     channel.setMethodCallHandler(instance.handleMethodCall);
///   }
///   // ...
/// }
/// ```
class Registrar extends BinaryMessenger {
  /// Creates a [Registrar].
  ///
  /// The argument is ignored. To create a test [Registrar] with custom behavior,
  /// subclass the [Registrar] class and override methods as appropriate.
  Registrar([
    @Deprecated(
      'This argument is ignored. '
      'This feature was deprecated after v1.24.0-7.0.pre.'
    )
    BinaryMessenger? binaryMessenger,
  ]);

  /// Registers the registrar's message handler
  /// ([handlePlatformMessage]) with the engine, so that plugin
  /// messages are correctly dispatched to the relevant registered
  /// plugin.
  ///
  /// Only one handler can be registered at a time. Calling this
  /// method a second time silently unregisters any
  /// previously-registered handler and replaces it with the handler
  /// from this object.
  ///
  /// This method uses a function called `webOnlySetPluginHandler` in
  /// the [dart:ui] library. That function is only available when
  /// compiling for the web.
  void registerMessageHandler() {
    // The `ui.webOnlySetPluginHandler` function below is only defined in the Web dart:ui.
    // ignore: undefined_function, avoid_dynamic_calls
    ui.webOnlySetPluginHandler(handleFrameworkMessage);
  }

  /// Receives a platform message from the framework.
  ///
  /// This method has been replaced with the more clearly-named [handleFrameworkMessage].
  @Deprecated(
    'Use handleFrameworkMessage instead. '
    'This feature was deprecated after v1.24.0-7.0.pre.'
  )
  @override
  Future<void> handlePlatformMessage(
    String channel,
    ByteData? data,
    ui.PlatformMessageResponseCallback? callback,
  ) => handleFrameworkMessage(channel, data, callback);

  /// Message handler for web plugins.
  ///
  /// This method is called when handling messages from the framework.
  ///
  /// If a handler has been registered for the given `channel`, it is
  /// invoked, and the value it returns is passed to `callback` (if that
  /// is non-null). Then, the method's future is completed.
  ///
  /// If no handler has been registered for that channel, then the
  /// callback (if any) is invoked with null, then the method's future
  /// is completed.
  ///
  /// Messages are not buffered (unlike platform messages headed to
  /// the framework, which are managed by [ChannelBuffers]).
  ///
  /// This method is registered as the message handler by code
  /// autogenerated by the `flutter` tool when the application is
  /// compiled, if any web plugins are used. The code in question is
  /// the following:
  ///
  /// ```dart
  /// ui.webOnlySetPluginHandler(webPluginRegistrar.handleFrameworkMessage);
  /// ```
  Future<void> handleFrameworkMessage(
    String channel,
    ByteData? data,
    ui.PlatformMessageResponseCallback? callback,
  ) async {
    ByteData? response;
    try {
      final MessageHandler? handler = _handlers[channel];
      if (handler != null) {
        response = await handler(data);
      }
    } catch (exception, stack) {
      FlutterError.reportError(FlutterErrorDetails(
        exception: exception,
        stack: stack,
        library: 'flutter web plugins',
        context: ErrorDescription('during a framework-to-plugin message'),
      ));
    } finally {
      if (callback != null) {
        callback(response);
      }
    }
  }

  /// Returns `this`.
  @Deprecated(
    'This property is redundant. It returns the object on which it is called. '
    'This feature was deprecated after v1.24.0-7.0.pre.'
  )
  BinaryMessenger get messenger => this;

  final Map<String, MessageHandler> _handlers = <String, MessageHandler>{};

  /// Sends a platform message from the platform side back to the framework.
  @override
  Future<ByteData?> send(String channel, ByteData? message) {
    final Completer<ByteData?> completer = Completer<ByteData?>();
    ui.channelBuffers.push(channel, message, (ByteData? reply) {
      try {
        completer.complete(reply);
      } catch (exception, stack) {
        FlutterError.reportError(FlutterErrorDetails(
          exception: exception,
          stack: stack,
          library: 'flutter web plugins',
          context: ErrorDescription('during a plugin-to-framework message'),
        ));
      }
    });
    return completer.future;
  }

  @override
  void setMessageHandler(String channel, MessageHandler? handler) {
    if (handler == null) {
      _handlers.remove(channel);
    } else {
      _handlers[channel] = handler;
    }
  }
}

/// This class was previously separate from [Registrar] but was merged into it
/// as part of a simplification of the web plugins API.
@Deprecated(
  'Use Registrar instead. '
  'This feature was deprecated after v1.26.0-18.0.pre.'
)
class PluginRegistry extends Registrar {
  /// Creates a [Registrar].
  ///
  /// The argument is ignored.
  @Deprecated(
    'Use Registrar instead. '
    'This feature was deprecated after v1.26.0-18.0.pre.'
  )
  PluginRegistry([
    @Deprecated(
      'This argument is ignored. '
      'This feature was deprecated after v1.26.0-18.0.pre.'
    )
    BinaryMessenger? binaryMessenger,
  ]) : super();

  /// Returns `this`. The argument is ignored.
  @Deprecated(
    'This method is redundant. It returns the object on which it is called. '
    'This feature was deprecated after v1.26.0-18.0.pre.'
  )
  Registrar registrarFor(Type key) => this;
}

/// The default plugin registrar for the web.
final Registrar webPluginRegistrar = PluginRegistry();

/// A deprecated alias for [webPluginRegistrar].
@Deprecated(
  'Use webPluginRegistrar instead. '
  'This feature was deprecated after v1.24.0-7.0.pre.'
)
PluginRegistry get webPluginRegistry => webPluginRegistrar as PluginRegistry;

/// A deprecated alias for [webPluginRegistrar].
@Deprecated(
  'Use webPluginRegistrar instead. '
  'This feature was deprecated after v1.24.0-7.0.pre.'
)
BinaryMessenger get pluginBinaryMessenger => webPluginRegistrar;
