/*
 * Purple Zulip - Zulip Protocol Plugin
 * Copyright (C) Pidgin Developers <devel@pidgin.im>
 *
 * Purple Zulip is the legal property of its developers, whose names are too
 * numerous to list here. Please refer to the COPYRIGHT file distributed with
 * this source distribution.
 *
 * This plugin is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This plugin is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this plugin; if not, see <https://www.gnu.org/licenses/>.
 */

#include <glib/gi18n-lib.h>

#include <birb.h>

#include "purplezulipprotocolconversation.h"

#include "purplezulipclient.h"
#include "purplezulipconnection.h"
#include "purplezulipresponses.h"

/******************************************************************************
 * SendMessage implementation
 *****************************************************************************/
static void
purple_zulip_protocol_conversation_send_message_cb(GObject *source,
                                                   GAsyncResult *result,
                                                   gpointer data)
{
	PurpleZulipClient *client = PURPLE_ZULIP_CLIENT(source);
	PurpleZulipSendMessageResponse *response = NULL;
	GError *error = NULL;
	GTask *task = data;

	response = purple_zulip_client_send_message_finish(client, result, &error);
	if(error != NULL) {
		g_task_return_error(task, error);
	} else {
		PurpleMessage *message = NULL;
		char *id = NULL;

		message = g_task_get_task_data(task);

		id = g_strdup_printf("%" G_GINT64_FORMAT, response->id);
		purple_message_set_id(message, id);
		g_clear_pointer(&id, g_free);

		purple_message_set_delivered(message, TRUE);
	}

	g_clear_pointer(&response, purple_zulip_send_message_response_free);
	g_clear_object(&task);
}

static void
purple_zulip_protocol_conversation_send_message_async(PurpleProtocolConversation *protocol,
                                                      PurpleConversation *conversation,
                                                      PurpleMessage *message,
                                                      GCancellable *cancellable,
                                                      GAsyncReadyCallback callback,
                                                      gpointer data)
{
	PurpleZulipClient *client = NULL;
	PurpleZulipConnection *connection = NULL;
	PurpleAccount *account = NULL;
	PurpleConnection *purple_connection = NULL;
	GTask *task = NULL;

	task = g_task_new(protocol, cancellable, callback, data);
	g_task_set_task_data(task, g_object_ref(message), g_object_unref);

	account = purple_conversation_get_account(conversation);
	purple_connection = purple_account_get_connection(account);
	connection = PURPLE_ZULIP_CONNECTION(purple_connection);
	client = purple_zulip_connection_get_client(connection);

	purple_zulip_client_send_message_async(client, conversation, message,
	                                       purple_zulip_protocol_conversation_send_message_cb,
	                                       task);
}

static gboolean
purple_zulip_protocol_conversation_send_message_finish(G_GNUC_UNUSED PurpleProtocolConversation *protocol,
                                                       GAsyncResult *result,
                                                       GError **error)
{
	g_return_val_if_fail(G_IS_TASK(result), FALSE);

	return g_task_propagate_boolean(G_TASK(result), error);
}

static void
purple_zulip_protocol_conversation_send_typing(G_GNUC_UNUSED PurpleProtocolConversation *protocol,
                                               PurpleConversation *conversation,
                                               PurpleTypingState typing_state)
{
	PurpleZulipClient *client = NULL;
	PurpleAccount *account = NULL;
	PurpleConnection *connection = NULL;

	account = purple_conversation_get_account(conversation);
	connection = purple_account_get_connection(account);
	client = purple_zulip_connection_get_client(PURPLE_ZULIP_CONNECTION(connection));

	purple_zulip_client_send_typing(client, conversation, typing_state);
}

void
purple_zulip_protocol_conversation_init(PurpleProtocolConversationInterface *iface) {
	iface->send_message_async = purple_zulip_protocol_conversation_send_message_async;
	iface->send_message_finish = purple_zulip_protocol_conversation_send_message_finish;

	iface->send_typing = purple_zulip_protocol_conversation_send_typing;
}
