// 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_basic_message_channel.h"

#include <gmodule.h>

struct _FlBasicMessageChannel {
  GObject parent_instance;

  // Messenger to communicate on.
  FlBinaryMessenger* messenger;

  // TRUE if the channel has been closed.
  gboolean channel_closed;

  // Channel name.
  gchar* name;

  // Codec to en/decode messages.
  FlMessageCodec* codec;

  // Function called when a message is received.
  FlBasicMessageChannelMessageHandler message_handler;
  gpointer message_handler_data;
  GDestroyNotify message_handler_destroy_notify;
};

struct _FlBasicMessageChannelResponseHandle {
  GObject parent_instance;

  FlBinaryMessengerResponseHandle* response_handle;
};

// Added here to stop the compiler from optimizing this function away.
G_MODULE_EXPORT GType fl_basic_message_channel_get_type();

G_DEFINE_TYPE(FlBasicMessageChannel, fl_basic_message_channel, G_TYPE_OBJECT)
G_DEFINE_TYPE(FlBasicMessageChannelResponseHandle,
              fl_basic_message_channel_response_handle,
              G_TYPE_OBJECT)

static void fl_basic_message_channel_response_handle_dispose(GObject* object) {
  FlBasicMessageChannelResponseHandle* self =
      FL_BASIC_MESSAGE_CHANNEL_RESPONSE_HANDLE(object);

  g_clear_object(&self->response_handle);

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

static void fl_basic_message_channel_response_handle_class_init(
    FlBasicMessageChannelResponseHandleClass* klass) {
  G_OBJECT_CLASS(klass)->dispose =
      fl_basic_message_channel_response_handle_dispose;
}

static void fl_basic_message_channel_response_handle_init(
    FlBasicMessageChannelResponseHandle* self) {}

static FlBasicMessageChannelResponseHandle*
fl_basic_message_channel_response_handle_new(
    FlBinaryMessengerResponseHandle* response_handle) {
  FlBasicMessageChannelResponseHandle* self =
      FL_BASIC_MESSAGE_CHANNEL_RESPONSE_HANDLE(g_object_new(
          fl_basic_message_channel_response_handle_get_type(), nullptr));

  self->response_handle =
      FL_BINARY_MESSENGER_RESPONSE_HANDLE(g_object_ref(response_handle));

  return self;
}

// Called when a binary message is received on this channel.
static void message_cb(FlBinaryMessenger* messenger,
                       const gchar* channel,
                       GBytes* message,
                       FlBinaryMessengerResponseHandle* response_handle,
                       gpointer user_data) {
  FlBasicMessageChannel* self = FL_BASIC_MESSAGE_CHANNEL(user_data);

  if (self->message_handler == nullptr) {
    fl_binary_messenger_send_response(messenger, response_handle, nullptr,
                                      nullptr);
    return;
  }

  g_autoptr(GError) error = nullptr;
  g_autoptr(FlValue) message_value =
      fl_message_codec_decode_message(self->codec, message, &error);
  if (message_value == nullptr) {
    g_warning("Failed to decode message: %s", error->message);
    fl_binary_messenger_send_response(messenger, response_handle, nullptr,
                                      nullptr);
  }

  g_autoptr(FlBasicMessageChannelResponseHandle) handle =
      fl_basic_message_channel_response_handle_new(response_handle);
  self->message_handler(self, message_value, handle,
                        self->message_handler_data);
}

// Called when a response is received to a sent message.
static void message_response_cb(GObject* object,
                                GAsyncResult* result,
                                gpointer user_data) {
  GTask* task = G_TASK(user_data);
  g_task_return_pointer(task, result, g_object_unref);
}

// Called when the channel handler is closed.
static void channel_closed_cb(gpointer user_data) {
  g_autoptr(FlBasicMessageChannel) self = FL_BASIC_MESSAGE_CHANNEL(user_data);

  self->channel_closed = TRUE;

  // Disconnect handler.
  if (self->message_handler_destroy_notify != nullptr) {
    self->message_handler_destroy_notify(self->message_handler_data);
  }
  self->message_handler = nullptr;
  self->message_handler_data = nullptr;
  self->message_handler_destroy_notify = nullptr;
}

static void fl_basic_message_channel_dispose(GObject* object) {
  FlBasicMessageChannel* self = FL_BASIC_MESSAGE_CHANNEL(object);

  if (self->messenger != nullptr) {
    fl_binary_messenger_set_message_handler_on_channel(
        self->messenger, self->name, nullptr, nullptr, nullptr);
  }

  g_clear_object(&self->messenger);
  g_clear_pointer(&self->name, g_free);
  g_clear_object(&self->codec);

  if (self->message_handler_destroy_notify != nullptr) {
    self->message_handler_destroy_notify(self->message_handler_data);
  }
  self->message_handler = nullptr;
  self->message_handler_data = nullptr;
  self->message_handler_destroy_notify = nullptr;

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

static void fl_basic_message_channel_class_init(
    FlBasicMessageChannelClass* klass) {
  G_OBJECT_CLASS(klass)->dispose = fl_basic_message_channel_dispose;
}

static void fl_basic_message_channel_init(FlBasicMessageChannel* self) {}

G_MODULE_EXPORT FlBasicMessageChannel* fl_basic_message_channel_new(
    FlBinaryMessenger* messenger,
    const gchar* name,
    FlMessageCodec* codec) {
  g_return_val_if_fail(FL_IS_BINARY_MESSENGER(messenger), nullptr);
  g_return_val_if_fail(name != nullptr, nullptr);
  g_return_val_if_fail(FL_IS_MESSAGE_CODEC(codec), nullptr);

  FlBasicMessageChannel* self = FL_BASIC_MESSAGE_CHANNEL(
      g_object_new(fl_basic_message_channel_get_type(), nullptr));

  self->messenger = FL_BINARY_MESSENGER(g_object_ref(messenger));
  self->name = g_strdup(name);
  self->codec = FL_MESSAGE_CODEC(g_object_ref(codec));

  fl_binary_messenger_set_message_handler_on_channel(
      self->messenger, self->name, message_cb, g_object_ref(self),
      channel_closed_cb);

  return self;
}

G_MODULE_EXPORT void fl_basic_message_channel_set_message_handler(
    FlBasicMessageChannel* self,
    FlBasicMessageChannelMessageHandler handler,
    gpointer user_data,
    GDestroyNotify destroy_notify) {
  g_return_if_fail(FL_IS_BASIC_MESSAGE_CHANNEL(self));

  // Don't set handler if channel closed.
  if (self->channel_closed) {
    if (handler != nullptr) {
      g_warning(
          "Attempted to set message handler on a closed FlBasicMessageChannel");
    }
    if (destroy_notify != nullptr) {
      destroy_notify(user_data);
    }
    return;
  }

  if (self->message_handler_destroy_notify != nullptr) {
    self->message_handler_destroy_notify(self->message_handler_data);
  }

  self->message_handler = handler;
  self->message_handler_data = user_data;
  self->message_handler_destroy_notify = destroy_notify;
}

G_MODULE_EXPORT gboolean fl_basic_message_channel_respond(
    FlBasicMessageChannel* self,
    FlBasicMessageChannelResponseHandle* response_handle,
    FlValue* message,
    GError** error) {
  g_return_val_if_fail(FL_IS_BASIC_MESSAGE_CHANNEL(self), FALSE);
  g_return_val_if_fail(response_handle != nullptr, FALSE);
  g_return_val_if_fail(response_handle->response_handle != nullptr, FALSE);

  g_autoptr(GBytes) data =
      fl_message_codec_encode_message(self->codec, message, error);
  if (data == nullptr) {
    return FALSE;
  }

  gboolean result = fl_binary_messenger_send_response(
      self->messenger, response_handle->response_handle, data, error);
  g_clear_object(&response_handle->response_handle);

  return result;
}

G_MODULE_EXPORT void fl_basic_message_channel_send(FlBasicMessageChannel* self,
                                                   FlValue* message,
                                                   GCancellable* cancellable,
                                                   GAsyncReadyCallback callback,
                                                   gpointer user_data) {
  g_return_if_fail(FL_IS_BASIC_MESSAGE_CHANNEL(self));
  g_return_if_fail(message != nullptr);

  g_autoptr(GTask) task =
      callback != nullptr ? g_task_new(self, cancellable, callback, user_data)
                          : nullptr;

  g_autoptr(GError) error = nullptr;
  g_autoptr(GBytes) data =
      fl_message_codec_encode_message(self->codec, message, &error);
  if (data == nullptr) {
    if (task != nullptr) {
      g_task_return_error(task, error);
    }
    return;
  }

  fl_binary_messenger_send_on_channel(
      self->messenger, self->name, data, cancellable,
      callback != nullptr ? message_response_cb : nullptr,
      g_steal_pointer(&task));
}

G_MODULE_EXPORT FlValue* fl_basic_message_channel_send_finish(
    FlBasicMessageChannel* self,
    GAsyncResult* result,
    GError** error) {
  g_return_val_if_fail(FL_IS_BASIC_MESSAGE_CHANNEL(self), nullptr);
  g_return_val_if_fail(g_task_is_valid(result, self), nullptr);

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

  g_autoptr(GBytes) message =
      fl_binary_messenger_send_on_channel_finish(self->messenger, r, error);
  if (message == nullptr) {
    return nullptr;
  }

  return fl_message_codec_decode_message(self->codec, message, error);
}
