// Copyright 2013 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.

#include "flutter/shell/platform/linux/public/flutter_linux/fl_binary_messenger.h"
#include "flutter/shell/platform/linux/fl_binary_messenger_private.h"

#include "flutter/fml/logging.h"
#include "flutter/shell/platform/linux/fl_engine_private.h"
#include "flutter/shell/platform/linux/fl_method_codec_private.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_engine.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_method_channel.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_method_codec.h"
#include "flutter/shell/platform/linux/public/flutter_linux/fl_standard_method_codec.h"

#include <gmodule.h>

static constexpr char kControlChannelName[] = "dev.flutter/channel-buffers";
static constexpr char kResizeMethod[] = "resize";
static constexpr char kOverflowMethod[] = "overflow";

G_DEFINE_QUARK(fl_binary_messenger_codec_error_quark,
               fl_binary_messenger_codec_error)

G_DECLARE_FINAL_TYPE(FlBinaryMessengerImpl,
                     fl_binary_messenger_impl,
                     FL,
                     BINARY_MESSENGER_IMPL,
                     GObject)

G_DECLARE_FINAL_TYPE(FlBinaryMessengerResponseHandleImpl,
                     fl_binary_messenger_response_handle_impl,
                     FL,
                     BINARY_MESSENGER_RESPONSE_HANDLE_IMPL,
                     FlBinaryMessengerResponseHandle)

G_DEFINE_INTERFACE(FlBinaryMessenger, fl_binary_messenger, G_TYPE_OBJECT)

struct _FlBinaryMessengerImpl {
  GObject parent_instance;

  GWeakRef engine;

  // PlatformMessageHandler keyed by channel name.
  GHashTable* platform_message_handlers;
};

static void fl_binary_messenger_impl_iface_init(
    FlBinaryMessengerInterface* iface);

G_DEFINE_TYPE_WITH_CODE(
    FlBinaryMessengerImpl,
    fl_binary_messenger_impl,
    G_TYPE_OBJECT,
    G_IMPLEMENT_INTERFACE(fl_binary_messenger_get_type(),
                          fl_binary_messenger_impl_iface_init))

static void fl_binary_messenger_response_handle_class_init(
    FlBinaryMessengerResponseHandleClass* klass) {}

G_DEFINE_TYPE(FlBinaryMessengerResponseHandle,
              fl_binary_messenger_response_handle,
              G_TYPE_OBJECT)

static void fl_binary_messenger_response_handle_init(
    FlBinaryMessengerResponseHandle* self) {}

struct _FlBinaryMessengerResponseHandleImpl {
  FlBinaryMessengerResponseHandle parent_instance;

  // Messenger sending response on.
  FlBinaryMessengerImpl* messenger;

  // Handle to send the response with. This is cleared to nullptr when it is
  // used.
  const FlutterPlatformMessageResponseHandle* response_handle;
};

G_DEFINE_TYPE(FlBinaryMessengerResponseHandleImpl,
              fl_binary_messenger_response_handle_impl,
              fl_binary_messenger_response_handle_get_type())

static void fl_binary_messenger_default_init(
    FlBinaryMessengerInterface* iface) {}

static void fl_binary_messenger_response_handle_impl_dispose(GObject* object) {
  FlBinaryMessengerResponseHandleImpl* self =
      FL_BINARY_MESSENGER_RESPONSE_HANDLE_IMPL(object);

  g_autoptr(FlEngine) engine =
      FL_ENGINE(g_weak_ref_get(&self->messenger->engine));
  if (self->response_handle != nullptr && engine != nullptr) {
    g_critical("FlBinaryMessengerResponseHandle was not responded to");
  }

  g_clear_object(&self->messenger);
  self->response_handle = nullptr;

  G_OBJECT_CLASS(fl_binary_messenger_response_handle_impl_parent_class)
      ->dispose(object);
}

static void fl_binary_messenger_response_handle_impl_class_init(
    FlBinaryMessengerResponseHandleImplClass* klass) {
  G_OBJECT_CLASS(klass)->dispose =
      fl_binary_messenger_response_handle_impl_dispose;
}

static void fl_binary_messenger_response_handle_impl_init(
    FlBinaryMessengerResponseHandleImpl* self) {}

static FlBinaryMessengerResponseHandleImpl*
fl_binary_messenger_response_handle_impl_new(
    FlBinaryMessengerImpl* messenger,
    const FlutterPlatformMessageResponseHandle* response_handle) {
  FlBinaryMessengerResponseHandleImpl* self =
      FL_BINARY_MESSENGER_RESPONSE_HANDLE_IMPL(g_object_new(
          fl_binary_messenger_response_handle_impl_get_type(), nullptr));

  self->messenger = FL_BINARY_MESSENGER_IMPL(g_object_ref(messenger));
  self->response_handle = response_handle;

  return self;
}

typedef struct {
  FlBinaryMessengerMessageHandler message_handler;
  gpointer message_handler_data;
  GDestroyNotify message_handler_destroy_notify;
} PlatformMessageHandler;

static PlatformMessageHandler* platform_message_handler_new(
    FlBinaryMessengerMessageHandler handler,
    gpointer user_data,
    GDestroyNotify destroy_notify) {
  PlatformMessageHandler* self = static_cast<PlatformMessageHandler*>(
      g_malloc0(sizeof(PlatformMessageHandler)));
  self->message_handler = handler;
  self->message_handler_data = user_data;
  self->message_handler_destroy_notify = destroy_notify;
  return self;
}

static void platform_message_handler_free(gpointer data) {
  PlatformMessageHandler* self = static_cast<PlatformMessageHandler*>(data);
  if (self->message_handler_destroy_notify) {
    self->message_handler_destroy_notify(self->message_handler_data);
  }
  g_free(self);
}

static void engine_weak_notify_cb(gpointer user_data,
                                  GObject* where_the_object_was) {
  FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(user_data);

  // Disconnect any handlers.
  // Take the reference in case a handler tries to modify this table.
  g_autoptr(GHashTable) handlers = self->platform_message_handlers;
  self->platform_message_handlers = g_hash_table_new_full(
      g_str_hash, g_str_equal, g_free, platform_message_handler_free);
  g_hash_table_remove_all(handlers);
}

static gboolean fl_binary_messenger_platform_message_cb(
    FlEngine* engine,
    const gchar* channel,
    GBytes* message,
    const FlutterPlatformMessageResponseHandle* response_handle,
    void* user_data) {
  FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(user_data);

  PlatformMessageHandler* handler = static_cast<PlatformMessageHandler*>(
      g_hash_table_lookup(self->platform_message_handlers, channel));
  if (handler == nullptr) {
    return FALSE;
  }

  g_autoptr(FlBinaryMessengerResponseHandleImpl) handle =
      fl_binary_messenger_response_handle_impl_new(self, response_handle);
  handler->message_handler(FL_BINARY_MESSENGER(self), channel, message,
                           FL_BINARY_MESSENGER_RESPONSE_HANDLE(handle),
                           handler->message_handler_data);

  return TRUE;
}

static void fl_binary_messenger_impl_dispose(GObject* object) {
  FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(object);

  {
    g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
    if (engine) {
      g_object_weak_unref(G_OBJECT(engine), engine_weak_notify_cb, self);
    }
  }

  g_weak_ref_clear(&self->engine);

  g_clear_pointer(&self->platform_message_handlers, g_hash_table_unref);

  G_OBJECT_CLASS(fl_binary_messenger_impl_parent_class)->dispose(object);
}

static void set_message_handler_on_channel(
    FlBinaryMessenger* messenger,
    const gchar* channel,
    FlBinaryMessengerMessageHandler handler,
    gpointer user_data,
    GDestroyNotify destroy_notify) {
  FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(messenger);

  // Don't set handlers if engine already gone.
  g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
  if (engine == nullptr) {
    if (handler != nullptr) {
      g_warning(
          "Attempted to set message handler on an FlBinaryMessenger without an "
          "engine");
    }
    if (destroy_notify != nullptr) {
      destroy_notify(user_data);
    }
    return;
  }

  if (handler != nullptr) {
    g_hash_table_replace(
        self->platform_message_handlers, g_strdup(channel),
        platform_message_handler_new(handler, user_data, destroy_notify));
  } else {
    g_hash_table_remove(self->platform_message_handlers, channel);
  }
}

static gboolean do_unref(gpointer value) {
  g_object_unref(value);
  return G_SOURCE_REMOVE;
}

// Note: This function can be called from any thread.
static gboolean send_response(FlBinaryMessenger* messenger,
                              FlBinaryMessengerResponseHandle* response_handle_,
                              GBytes* response,
                              GError** error) {
  FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(messenger);
  g_return_val_if_fail(
      FL_IS_BINARY_MESSENGER_RESPONSE_HANDLE_IMPL(response_handle_), FALSE);
  FlBinaryMessengerResponseHandleImpl* response_handle =
      FL_BINARY_MESSENGER_RESPONSE_HANDLE_IMPL(response_handle_);

  g_return_val_if_fail(response_handle->messenger == self, FALSE);
  g_return_val_if_fail(response_handle->response_handle != nullptr, FALSE);

  FlEngine* engine = FL_ENGINE(g_weak_ref_get(&self->engine));
  if (engine == nullptr) {
    return TRUE;
  }

  gboolean result = false;
  if (response_handle->response_handle == nullptr) {
    g_set_error(
        error, FL_BINARY_MESSENGER_ERROR,
        FL_BINARY_MESSENGER_ERROR_ALREADY_RESPONDED,
        "Attempted to respond to a message that is already responded to");
    result = FALSE;
  } else {
    result = fl_engine_send_platform_message_response(
        engine, response_handle->response_handle, response, error);
    response_handle->response_handle = nullptr;
  }

  // This guarantees that the dispose method for the engine is executed
  // on the platform thread in the rare chance this is the last ref.
  g_idle_add(do_unref, engine);

  return result;
}

static void platform_message_ready_cb(GObject* object,
                                      GAsyncResult* result,
                                      gpointer user_data) {
  GTask* task = G_TASK(user_data);
  g_task_return_pointer(task, result, g_object_unref);
}

static void send_on_channel(FlBinaryMessenger* messenger,
                            const gchar* channel,
                            GBytes* message,
                            GCancellable* cancellable,
                            GAsyncReadyCallback callback,
                            gpointer user_data) {
  FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(messenger);

  g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
  if (engine == nullptr) {
    return;
  }

  fl_engine_send_platform_message(
      engine, channel, message, cancellable,
      callback != nullptr ? platform_message_ready_cb : nullptr,
      callback != nullptr ? g_task_new(self, cancellable, callback, user_data)
                          : nullptr);
}

static GBytes* send_on_channel_finish(FlBinaryMessenger* messenger,
                                      GAsyncResult* result,
                                      GError** error) {
  FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(messenger);
  g_return_val_if_fail(g_task_is_valid(result, self), FALSE);

  g_autoptr(GTask) task = G_TASK(result);
  GAsyncResult* r = G_ASYNC_RESULT(g_task_propagate_pointer(task, nullptr));

  g_autoptr(FlEngine) engine = FL_ENGINE(g_weak_ref_get(&self->engine));
  if (engine == nullptr) {
    return nullptr;
  }

  return fl_engine_send_platform_message_finish(engine, r, error);
}

// Completes method call and returns TRUE if the call was successful.
static gboolean finish_method(GObject* object,
                              GAsyncResult* result,
                              GError** error) {
  g_autoptr(GBytes) response = fl_binary_messenger_send_on_channel_finish(
      FL_BINARY_MESSENGER(object), result, error);
  if (response == nullptr) {
    return FALSE;
  }
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  return fl_method_codec_decode_response(FL_METHOD_CODEC(codec), response,
                                         error) != nullptr;
}

// Called when a response is received for the resize channel message.
static void resize_channel_response_cb(GObject* object,
                                       GAsyncResult* result,
                                       gpointer user_data) {
  g_autoptr(GError) error = nullptr;
  if (!finish_method(object, result, &error)) {
    g_warning("Failed to resize channel: %s", error->message);
  }
}

static void resize_channel(FlBinaryMessenger* messenger,
                           const gchar* channel,
                           int64_t new_size) {
  FML_DCHECK(new_size >= 0);
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  g_autoptr(FlValue) args = fl_value_new_list();
  fl_value_append_take(args, fl_value_new_string(channel));
  fl_value_append_take(args, fl_value_new_int(new_size));
  g_autoptr(GBytes) message = fl_method_codec_encode_method_call(
      FL_METHOD_CODEC(codec), kResizeMethod, args, nullptr);
  fl_binary_messenger_send_on_channel(messenger, kControlChannelName, message,
                                      nullptr, resize_channel_response_cb,
                                      nullptr);
}

// Called when a response is received for the warns on overflow message.
static void set_warns_on_channel_overflow_response_cb(GObject* object,
                                                      GAsyncResult* result,
                                                      gpointer user_data) {
  g_autoptr(GError) error = nullptr;
  if (!finish_method(object, result, &error)) {
    g_warning("Failed to set warns on channel overflow: %s", error->message);
  }
}

static void set_warns_on_channel_overflow(FlBinaryMessenger* messenger,
                                          const gchar* channel,
                                          bool warns) {
  g_autoptr(FlStandardMethodCodec) codec = fl_standard_method_codec_new();
  g_autoptr(FlValue) args = fl_value_new_list();
  fl_value_append_take(args, fl_value_new_string(channel));
  fl_value_append_take(args, fl_value_new_bool(!warns));
  g_autoptr(GBytes) message = fl_method_codec_encode_method_call(
      FL_METHOD_CODEC(codec), kOverflowMethod, args, nullptr);
  fl_binary_messenger_send_on_channel(
      messenger, kControlChannelName, message, nullptr,
      set_warns_on_channel_overflow_response_cb, nullptr);
}

static void fl_binary_messenger_impl_class_init(
    FlBinaryMessengerImplClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_binary_messenger_impl_dispose;
}

static void fl_binary_messenger_impl_iface_init(
    FlBinaryMessengerInterface* iface) {
  iface->set_message_handler_on_channel = set_message_handler_on_channel;
  iface->send_response = send_response;
  iface->send_on_channel = send_on_channel;
  iface->send_on_channel_finish = send_on_channel_finish;
  iface->resize_channel = resize_channel;
  iface->set_warns_on_channel_overflow = set_warns_on_channel_overflow;
}

static void fl_binary_messenger_impl_init(FlBinaryMessengerImpl* self) {
  self->platform_message_handlers = g_hash_table_new_full(
      g_str_hash, g_str_equal, g_free, platform_message_handler_free);
}

FlBinaryMessenger* fl_binary_messenger_new(FlEngine* engine) {
  g_return_val_if_fail(FL_IS_ENGINE(engine), nullptr);

  FlBinaryMessengerImpl* self = FL_BINARY_MESSENGER_IMPL(
      g_object_new(fl_binary_messenger_impl_get_type(), nullptr));

  // Added to stop compiler complaining about an unused function.
  FL_IS_BINARY_MESSENGER_IMPL(self);

  g_weak_ref_init(&self->engine, G_OBJECT(engine));
  g_object_weak_ref(G_OBJECT(engine), engine_weak_notify_cb, self);

  fl_engine_set_platform_message_handler(
      engine, fl_binary_messenger_platform_message_cb, self, NULL);

  return FL_BINARY_MESSENGER(self);
}

G_MODULE_EXPORT void fl_binary_messenger_set_message_handler_on_channel(
    FlBinaryMessenger* self,
    const gchar* channel,
    FlBinaryMessengerMessageHandler handler,
    gpointer user_data,
    GDestroyNotify destroy_notify) {
  g_return_if_fail(FL_IS_BINARY_MESSENGER(self));
  g_return_if_fail(channel != nullptr);

  FL_BINARY_MESSENGER_GET_IFACE(self)->set_message_handler_on_channel(
      self, channel, handler, user_data, destroy_notify);
}

// Note: This function can be called from any thread.
G_MODULE_EXPORT gboolean fl_binary_messenger_send_response(
    FlBinaryMessenger* self,
    FlBinaryMessengerResponseHandle* response_handle,
    GBytes* response,
    GError** error) {
  g_return_val_if_fail(FL_IS_BINARY_MESSENGER(self), FALSE);
  g_return_val_if_fail(FL_IS_BINARY_MESSENGER_RESPONSE_HANDLE(response_handle),
                       FALSE);

  return FL_BINARY_MESSENGER_GET_IFACE(self)->send_response(
      self, response_handle, response, error);
}

G_MODULE_EXPORT void fl_binary_messenger_send_on_channel(
    FlBinaryMessenger* self,
    const gchar* channel,
    GBytes* message,
    GCancellable* cancellable,
    GAsyncReadyCallback callback,
    gpointer user_data) {
  g_return_if_fail(FL_IS_BINARY_MESSENGER(self));
  g_return_if_fail(channel != nullptr);

  FL_BINARY_MESSENGER_GET_IFACE(self)->send_on_channel(
      self, channel, message, cancellable, callback, user_data);
}

G_MODULE_EXPORT GBytes* fl_binary_messenger_send_on_channel_finish(
    FlBinaryMessenger* self,
    GAsyncResult* result,
    GError** error) {
  g_return_val_if_fail(FL_IS_BINARY_MESSENGER(self), FALSE);

  return FL_BINARY_MESSENGER_GET_IFACE(self)->send_on_channel_finish(
      self, result, error);
}

G_MODULE_EXPORT void fl_binary_messenger_resize_channel(FlBinaryMessenger* self,
                                                        const gchar* channel,
                                                        int64_t new_size) {
  g_return_if_fail(FL_IS_BINARY_MESSENGER(self));

  return FL_BINARY_MESSENGER_GET_IFACE(self)->resize_channel(self, channel,
                                                             new_size);
}

G_MODULE_EXPORT void fl_binary_messenger_set_warns_on_channel_overflow(
    FlBinaryMessenger* self,
    const gchar* channel,
    bool warns) {
  g_return_if_fail(FL_IS_BINARY_MESSENGER(self));

  return FL_BINARY_MESSENGER_GET_IFACE(self)->set_warns_on_channel_overflow(
      self, channel, warns);
}
