/*
 * QEMU DBus display
 *
 * Copyright (c) 2021 Marc-André Lureau <marcandre.lureau@redhat.com>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
#include "qemu/osdep.h"
#include "qemu/dbus.h"
#include "qemu/main-loop.h"
#include "qom/object_interfaces.h"
#include "sysemu/sysemu.h"
#include "qapi/error.h"
#include "trace.h"

#include "dbus.h"

#define MIME_TEXT_PLAIN_UTF8 "text/plain;charset=utf-8"

static void
dbus_clipboard_complete_request(
    DBusDisplay *dpy,
    GDBusMethodInvocation *invocation,
    QemuClipboardInfo *info,
    QemuClipboardType type)
{
    GVariant *v_data = g_variant_new_from_data(
        G_VARIANT_TYPE("ay"),
        info->types[type].data,
        info->types[type].size,
        TRUE,
        (GDestroyNotify)qemu_clipboard_info_unref,
        qemu_clipboard_info_ref(info));

    qemu_dbus_display1_clipboard_complete_request(
        dpy->clipboard, invocation,
        MIME_TEXT_PLAIN_UTF8, v_data);
}

static void
dbus_clipboard_update_info(DBusDisplay *dpy, QemuClipboardInfo *info)
{
    bool self_update = info->owner == &dpy->clipboard_peer;
    const char *mime[QEMU_CLIPBOARD_TYPE__COUNT + 1] = { 0, };
    DBusClipboardRequest *req;
    int i = 0;

    if (info->owner == NULL) {
        if (dpy->clipboard_proxy) {
            qemu_dbus_display1_clipboard_call_release(
                dpy->clipboard_proxy,
                info->selection,
                G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
        }
        return;
    }

    if (self_update || !info->has_serial) {
        return;
    }

    req = &dpy->clipboard_request[info->selection];
    if (req->invocation && info->types[req->type].data) {
        dbus_clipboard_complete_request(dpy, req->invocation, info, req->type);
        g_clear_object(&req->invocation);
        g_source_remove(req->timeout_id);
        req->timeout_id = 0;
        return;
    }

    if (info->types[QEMU_CLIPBOARD_TYPE_TEXT].available) {
        mime[i++] = MIME_TEXT_PLAIN_UTF8;
    }

    if (i > 0) {
        if (dpy->clipboard_proxy) {
            qemu_dbus_display1_clipboard_call_grab(
                dpy->clipboard_proxy,
                info->selection,
                info->serial,
                mime,
                G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
        }
    }
}

static void
dbus_clipboard_reset_serial(DBusDisplay *dpy)
{
    if (dpy->clipboard_proxy) {
        qemu_dbus_display1_clipboard_call_register(
            dpy->clipboard_proxy,
            G_DBUS_CALL_FLAGS_NONE,
            -1, NULL, NULL, NULL);
    }
}

static void
dbus_clipboard_notify(Notifier *notifier, void *data)
{
    DBusDisplay *dpy =
        container_of(notifier, DBusDisplay, clipboard_peer.notifier);
    QemuClipboardNotify *notify = data;

    switch (notify->type) {
    case QEMU_CLIPBOARD_UPDATE_INFO:
        dbus_clipboard_update_info(dpy, notify->info);
        return;
    case QEMU_CLIPBOARD_RESET_SERIAL:
        dbus_clipboard_reset_serial(dpy);
        return;
    }
}

static void
dbus_clipboard_qemu_request(QemuClipboardInfo *info,
                            QemuClipboardType type)
{
    DBusDisplay *dpy = container_of(info->owner, DBusDisplay, clipboard_peer);
    g_autofree char *mime = NULL;
    g_autoptr(GVariant) v_data = NULL;
    g_autoptr(GError) err = NULL;
    const char *data = NULL;
    const char *mimes[] = { MIME_TEXT_PLAIN_UTF8, NULL };
    size_t n;

    if (type != QEMU_CLIPBOARD_TYPE_TEXT) {
        /* unsupported atm */
        return;
    }

    if (dpy->clipboard_proxy) {
        if (!qemu_dbus_display1_clipboard_call_request_sync(
                dpy->clipboard_proxy,
                info->selection,
                mimes,
                G_DBUS_CALL_FLAGS_NONE, -1, &mime, &v_data, NULL, &err)) {
            error_report("Failed to request clipboard: %s", err->message);
            return;
        }

        if (g_strcmp0(mime, MIME_TEXT_PLAIN_UTF8)) {
            error_report("Unsupported returned MIME: %s", mime);
            return;
        }

        data = g_variant_get_fixed_array(v_data, &n, 1);
        qemu_clipboard_set_data(&dpy->clipboard_peer, info, type,
                                n, data, true);
    }
}

static void
dbus_clipboard_request_cancelled(DBusClipboardRequest *req)
{
    if (!req->invocation) {
        return;
    }

    g_dbus_method_invocation_return_error(
        req->invocation,
        DBUS_DISPLAY_ERROR,
        DBUS_DISPLAY_ERROR_FAILED,
        "Cancelled clipboard request");

    g_clear_object(&req->invocation);
    g_source_remove(req->timeout_id);
    req->timeout_id = 0;
}

static void
dbus_clipboard_unregister_proxy(DBusDisplay *dpy)
{
    const char *name = NULL;
    int i;

    for (i = 0; i < G_N_ELEMENTS(dpy->clipboard_request); ++i) {
        dbus_clipboard_request_cancelled(&dpy->clipboard_request[i]);
    }

    if (!dpy->clipboard_proxy) {
        return;
    }

    name = g_dbus_proxy_get_name(G_DBUS_PROXY(dpy->clipboard_proxy));
    trace_dbus_clipboard_unregister(name);
    g_clear_object(&dpy->clipboard_proxy);
}

static void
dbus_on_clipboard_proxy_name_owner_changed(
    DBusDisplay *dpy,
    GObject *object,
    GParamSpec *pspec)
{
    dbus_clipboard_unregister_proxy(dpy);
}

static gboolean
dbus_clipboard_register(
    DBusDisplay *dpy,
    GDBusMethodInvocation *invocation)
{
    g_autoptr(GError) err = NULL;
    const char *name = NULL;

    if (dpy->clipboard_proxy) {
        g_dbus_method_invocation_return_error(
            invocation,
            DBUS_DISPLAY_ERROR,
            DBUS_DISPLAY_ERROR_FAILED,
            "Clipboard peer already registered!");
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    dpy->clipboard_proxy =
        qemu_dbus_display1_clipboard_proxy_new_sync(
            g_dbus_method_invocation_get_connection(invocation),
            G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
            g_dbus_method_invocation_get_sender(invocation),
            "/org/qemu/Display1/Clipboard",
            NULL,
            &err);
    if (!dpy->clipboard_proxy) {
        g_dbus_method_invocation_return_error(
            invocation,
            DBUS_DISPLAY_ERROR,
            DBUS_DISPLAY_ERROR_FAILED,
            "Failed to setup proxy: %s", err->message);
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    name = g_dbus_proxy_get_name(G_DBUS_PROXY(dpy->clipboard_proxy));
    trace_dbus_clipboard_register(name);

    g_object_connect(dpy->clipboard_proxy,
                     "swapped-signal::notify::g-name-owner",
                     dbus_on_clipboard_proxy_name_owner_changed, dpy,
                     NULL);
    qemu_clipboard_reset_serial();

    qemu_dbus_display1_clipboard_complete_register(dpy->clipboard, invocation);
    return DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
dbus_clipboard_check_caller(DBusDisplay *dpy, GDBusMethodInvocation *invocation)
{
    if (!dpy->clipboard_proxy ||
        g_strcmp0(g_dbus_proxy_get_name(G_DBUS_PROXY(dpy->clipboard_proxy)),
                  g_dbus_method_invocation_get_sender(invocation))) {
        g_dbus_method_invocation_return_error(
            invocation,
            DBUS_DISPLAY_ERROR,
            DBUS_DISPLAY_ERROR_FAILED,
            "Unregistered caller");
        return FALSE;
    }

    return TRUE;
}

static gboolean
dbus_clipboard_unregister(
    DBusDisplay *dpy,
    GDBusMethodInvocation *invocation)
{
    if (!dbus_clipboard_check_caller(dpy, invocation)) {
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    dbus_clipboard_unregister_proxy(dpy);

    qemu_dbus_display1_clipboard_complete_unregister(
        dpy->clipboard, invocation);

    return DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
dbus_clipboard_grab(
    DBusDisplay *dpy,
    GDBusMethodInvocation *invocation,
    gint arg_selection,
    guint arg_serial,
    const gchar *const *arg_mimes)
{
    QemuClipboardSelection s = arg_selection;
    g_autoptr(QemuClipboardInfo) info = NULL;

    if (!dbus_clipboard_check_caller(dpy, invocation)) {
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    if (s >= QEMU_CLIPBOARD_SELECTION__COUNT) {
        g_dbus_method_invocation_return_error(
            invocation,
            DBUS_DISPLAY_ERROR,
            DBUS_DISPLAY_ERROR_FAILED,
            "Invalid clipboard selection: %d", arg_selection);
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    info = qemu_clipboard_info_new(&dpy->clipboard_peer, s);
    if (g_strv_contains(arg_mimes, MIME_TEXT_PLAIN_UTF8)) {
        info->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
    }
    info->serial = arg_serial;
    info->has_serial = true;
    if (qemu_clipboard_check_serial(info, true)) {
        qemu_clipboard_update(info);
    } else {
        trace_dbus_clipboard_grab_failed();
    }

    qemu_dbus_display1_clipboard_complete_grab(dpy->clipboard, invocation);
    return DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
dbus_clipboard_release(
    DBusDisplay *dpy,
    GDBusMethodInvocation *invocation,
    gint arg_selection)
{
    if (!dbus_clipboard_check_caller(dpy, invocation)) {
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    qemu_clipboard_peer_release(&dpy->clipboard_peer, arg_selection);

    qemu_dbus_display1_clipboard_complete_release(dpy->clipboard, invocation);
    return DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
dbus_clipboard_request_timeout(gpointer user_data)
{
    dbus_clipboard_request_cancelled(user_data);
    return G_SOURCE_REMOVE;
}

static gboolean
dbus_clipboard_request(
    DBusDisplay *dpy,
    GDBusMethodInvocation *invocation,
    gint arg_selection,
    const gchar *const *arg_mimes)
{
    QemuClipboardSelection s = arg_selection;
    QemuClipboardType type = QEMU_CLIPBOARD_TYPE_TEXT;
    QemuClipboardInfo *info = NULL;

    if (!dbus_clipboard_check_caller(dpy, invocation)) {
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    if (s >= QEMU_CLIPBOARD_SELECTION__COUNT) {
        g_dbus_method_invocation_return_error(
            invocation,
            DBUS_DISPLAY_ERROR,
            DBUS_DISPLAY_ERROR_FAILED,
            "Invalid clipboard selection: %d", arg_selection);
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    if (dpy->clipboard_request[s].invocation) {
        g_dbus_method_invocation_return_error(
            invocation,
            DBUS_DISPLAY_ERROR,
            DBUS_DISPLAY_ERROR_FAILED,
            "Pending request");
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    info = qemu_clipboard_info(s);
    if (!info || !info->owner || info->owner == &dpy->clipboard_peer) {
        g_dbus_method_invocation_return_error(
            invocation,
            DBUS_DISPLAY_ERROR,
            DBUS_DISPLAY_ERROR_FAILED,
            "Empty clipboard");
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    if (!g_strv_contains(arg_mimes, MIME_TEXT_PLAIN_UTF8) ||
        !info->types[type].available) {
        g_dbus_method_invocation_return_error(
            invocation,
            DBUS_DISPLAY_ERROR,
            DBUS_DISPLAY_ERROR_FAILED,
            "Unhandled MIME types requested");
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    if (info->types[type].data) {
        dbus_clipboard_complete_request(dpy, invocation, info, type);
    } else {
        qemu_clipboard_request(info, type);

        dpy->clipboard_request[s].invocation = g_object_ref(invocation);
        dpy->clipboard_request[s].type = type;
        dpy->clipboard_request[s].timeout_id =
            g_timeout_add_seconds(5, dbus_clipboard_request_timeout,
                                  &dpy->clipboard_request[s]);
    }

    return DBUS_METHOD_INVOCATION_HANDLED;
}

void
dbus_clipboard_init(DBusDisplay *dpy)
{
    g_autoptr(GDBusObjectSkeleton) clipboard = NULL;

    assert(!dpy->clipboard);

    clipboard = g_dbus_object_skeleton_new(DBUS_DISPLAY1_ROOT "/Clipboard");
    dpy->clipboard = qemu_dbus_display1_clipboard_skeleton_new();
    g_object_connect(dpy->clipboard,
                     "swapped-signal::handle-register",
                     dbus_clipboard_register, dpy,
                     "swapped-signal::handle-unregister",
                     dbus_clipboard_unregister, dpy,
                     "swapped-signal::handle-grab",
                     dbus_clipboard_grab, dpy,
                     "swapped-signal::handle-release",
                     dbus_clipboard_release, dpy,
                     "swapped-signal::handle-request",
                     dbus_clipboard_request, dpy,
                     NULL);

    g_dbus_object_skeleton_add_interface(
        G_DBUS_OBJECT_SKELETON(clipboard),
        G_DBUS_INTERFACE_SKELETON(dpy->clipboard));
    g_dbus_object_manager_server_export(dpy->server, clipboard);
    dpy->clipboard_peer.name = "dbus";
    dpy->clipboard_peer.notifier.notify = dbus_clipboard_notify;
    dpy->clipboard_peer.request = dbus_clipboard_qemu_request;
    qemu_clipboard_peer_register(&dpy->clipboard_peer);
}
