// Copyright 2019 The Chromium 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';

typedef _MessageHandler = Future<ByteData> Function(ByteData);

/// This class registers web platform plugins.
class PluginRegistry {
  /// Creates a plugin registry.
  PluginRegistry(this._binaryMessenger);

  final BinaryMessenger _binaryMessenger;

  /// Creates a registrar for the given plugin implementation class.
  Registrar registrarFor(Type key) => Registrar(_binaryMessenger);

  /// Registers this plugin handler with the engine, so that unrecognized
  /// platform messages are forwarded to the registry, where they can be
  /// correctly dispatched to one of the registered plugins.
  void registerMessageHandler() {
    // The function below is only defined in the Web dart:ui.
    // ignore: undefined_function
    ui.webOnlySetPluginHandler(_binaryMessenger.handlePlatformMessage);
  }
}

/// A registrar for a particular plugin.
///
/// Gives access to a [BinaryMessenger] which has been configured to receive
/// platform messages from the framework side.
class Registrar {
  /// Creates a registrar with the given [BinaryMessenger].
  Registrar(this.messenger);

  /// A [BinaryMessenger] configured to receive platform messages from the
  /// framework side.
  ///
  /// Use this [BinaryMessenger] when creating platform channels in order for
  /// them to receive messages from the platform side. For example:
  ///
  ///
  ///     class MyPlugin {
  ///       static void registerWith(Registrar registrar) {
  ///         final MethodChannel channel = MethodChannel(
  ///             'com.my_plugin/my_plugin',
  ///             const StandardMethodCodec(),
  ///             registrar.messenger);
  ///         final MyPlugin instance = MyPlugin();
  ///         channel.setMethodCallHandler(instance.handleMethodCall);
  ///       }
  ///       ...
  ///     }
  final BinaryMessenger messenger;
}

/// The default plugin registry for the web.
final PluginRegistry webPluginRegistry = PluginRegistry(pluginBinaryMessenger);

/// A [BinaryMessenger] which does the inverse of the default framework
/// messenger.
///
/// Instead of sending messages from the framework to the engine, this
/// receives messages from the framework and dispatches them to registered
/// plugins.
class _PlatformBinaryMessenger extends BinaryMessenger {
  final Map<String, _MessageHandler> _handlers = <String, _MessageHandler>{};

  /// Receives a platform message from the framework.
  @override
  Future<void> handlePlatformMessage(String channel, ByteData data,
      ui.PlatformMessageResponseCallback callback) async {
    ByteData response;
    try {
      final MessageHandler handler = _handlers[channel];
      if (handler != null) {
        response = await handler(data);
      } else {
        ui.channelBuffers.push(channel, data, callback);
      }
    } catch (exception, stack) {
      FlutterError.reportError(FlutterErrorDetails(
        exception: exception,
        stack: stack,
        library: 'flutter web shell',
        context: ErrorDescription('during a plugin platform message call'),
      ));
    } finally {
      callback(response);
    }
  }

  /// 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.window.onPlatformMessage(channel, message, (ByteData reply) {
      try {
        completer.complete(reply);
      } catch (exception, stack) {
        FlutterError.reportError(FlutterErrorDetails(
          exception: exception,
          stack: stack,
          library: 'flutter web shell',
          context: ErrorDescription('during a plugin-to-framework message'),
        ));
      }
    });
    return completer.future;
  }

  @override
  void setMessageHandler(
      String channel, Future<ByteData> Function(ByteData message) handler) {
    if (handler == null)
      _handlers.remove(channel);
    else
      _handlers[channel] = handler;
    ui.channelBuffers.drain(channel, (ByteData data, ui.PlatformMessageResponseCallback callback) async {
      await handlePlatformMessage(channel, data, callback);
    });
  }

  @override
  void setMockMessageHandler(
      String channel, Future<ByteData> Function(ByteData message) handler) {
    throw FlutterError(
        'Setting mock handlers is not supported on the platform side.');
  }
}

/// The default [BinaryMessenger] for Flutter Web plugins.
final BinaryMessenger pluginBinaryMessenger = _PlatformBinaryMessenger();
