/*
 * QEMU VNC display driver -- clipboard support
 *
 * Copyright (C) 2021 Gerd Hoffmann <kraxel@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-common.h"
#include "vnc.h"
#include "vnc-jobs.h"

static uint8_t *inflate_buffer(uint8_t *in, uint32_t in_len, uint32_t *size)
{
    z_stream stream = {
        .next_in  = in,
        .avail_in = in_len,
        .zalloc   = Z_NULL,
        .zfree    = Z_NULL,
    };
    uint32_t out_len = 8;
    uint8_t *out = g_malloc(out_len);
    int ret;

    stream.next_out = out + stream.total_out;
    stream.avail_out = out_len - stream.total_out;

    ret = inflateInit(&stream);
    if (ret != Z_OK) {
        goto err;
    }

    while (stream.avail_in) {
        ret = inflate(&stream, Z_FINISH);
        switch (ret) {
        case Z_OK:
        case Z_STREAM_END:
            break;
        case Z_BUF_ERROR:
            out_len <<= 1;
            if (out_len > (1 << 20)) {
                goto err_end;
            }
            out = g_realloc(out, out_len);
            stream.next_out = out + stream.total_out;
            stream.avail_out = out_len - stream.total_out;
            break;
        default:
            goto err_end;
        }
    }

    *size = stream.total_out;
    inflateEnd(&stream);

    return out;

err_end:
    inflateEnd(&stream);
err:
    g_free(out);
    return NULL;
}

static uint8_t *deflate_buffer(uint8_t *in, uint32_t in_len, uint32_t *size)
{
    z_stream stream = {
        .next_in  = in,
        .avail_in = in_len,
        .zalloc   = Z_NULL,
        .zfree    = Z_NULL,
    };
    uint32_t out_len = 8;
    uint8_t *out = g_malloc(out_len);
    int ret;

    stream.next_out = out + stream.total_out;
    stream.avail_out = out_len - stream.total_out;

    ret = deflateInit(&stream, Z_DEFAULT_COMPRESSION);
    if (ret != Z_OK) {
        goto err;
    }

    while (ret != Z_STREAM_END) {
        ret = deflate(&stream, Z_FINISH);
        switch (ret) {
        case Z_OK:
        case Z_STREAM_END:
            break;
        case Z_BUF_ERROR:
            out_len <<= 1;
            if (out_len > (1 << 20)) {
                goto err_end;
            }
            out = g_realloc(out, out_len);
            stream.next_out = out + stream.total_out;
            stream.avail_out = out_len - stream.total_out;
            break;
        default:
            goto err_end;
        }
    }

    *size = stream.total_out;
    deflateEnd(&stream);

    return out;

err_end:
    deflateEnd(&stream);
err:
    g_free(out);
    return NULL;
}

static void vnc_clipboard_send(VncState *vs, uint32_t count, uint32_t *dwords)
{
    int i;

    vnc_lock_output(vs);
    vnc_write_u8(vs, VNC_MSG_SERVER_CUT_TEXT);
    vnc_write_u8(vs, 0);
    vnc_write_u8(vs, 0);
    vnc_write_u8(vs, 0);
    vnc_write_s32(vs, -(count * sizeof(uint32_t)));  /* -(message length) */
    for (i = 0; i < count; i++) {
        vnc_write_u32(vs, dwords[i]);
    }
    vnc_unlock_output(vs);
    vnc_flush(vs);
}

static void vnc_clipboard_provide(VncState *vs,
                                  QemuClipboardInfo *info,
                                  QemuClipboardType type)
{
    uint32_t flags = 0;
    g_autofree uint8_t *buf = NULL;
    g_autofree void *zbuf = NULL;
    uint32_t zsize;

    switch (type) {
    case QEMU_CLIPBOARD_TYPE_TEXT:
        flags |= VNC_CLIPBOARD_TEXT;
        break;
    default:
        return;
    }
    flags |= VNC_CLIPBOARD_PROVIDE;

    buf = g_malloc(info->types[type].size + 4);
    buf[0] = (info->types[type].size >> 24) & 0xff;
    buf[1] = (info->types[type].size >> 16) & 0xff;
    buf[2] = (info->types[type].size >>  8) & 0xff;
    buf[3] = (info->types[type].size >>  0) & 0xff;
    memcpy(buf + 4, info->types[type].data, info->types[type].size);
    zbuf = deflate_buffer(buf, info->types[type].size + 4, &zsize);
    if (!zbuf) {
        return;
    }

    vnc_lock_output(vs);
    vnc_write_u8(vs, VNC_MSG_SERVER_CUT_TEXT);
    vnc_write_u8(vs, 0);
    vnc_write_u8(vs, 0);
    vnc_write_u8(vs, 0);
    vnc_write_s32(vs, -(sizeof(uint32_t) + zsize));  /* -(message length) */
    vnc_write_u32(vs, flags);
    vnc_write(vs, zbuf, zsize);
    vnc_unlock_output(vs);
    vnc_flush(vs);
}

static void vnc_clipboard_update_info(VncState *vs, QemuClipboardInfo *info)
{
    QemuClipboardType type;
    bool self_update = info->owner == &vs->cbpeer;
    uint32_t flags = 0;

    if (info != vs->cbinfo) {
        qemu_clipboard_info_unref(vs->cbinfo);
        vs->cbinfo = qemu_clipboard_info_ref(info);
        vs->cbpending = 0;
        if (!self_update) {
            if (info->types[QEMU_CLIPBOARD_TYPE_TEXT].available) {
                flags |= VNC_CLIPBOARD_TEXT;
            }
            flags |= VNC_CLIPBOARD_NOTIFY;
            vnc_clipboard_send(vs, 1, &flags);
        }
        return;
    }

    if (self_update) {
        return;
    }

    for (type = 0; type < QEMU_CLIPBOARD_TYPE__COUNT; type++) {
        if (vs->cbpending & (1 << type)) {
            vs->cbpending &= ~(1 << type);
            vnc_clipboard_provide(vs, info, type);
        }
    }
}

static void vnc_clipboard_notify(Notifier *notifier, void *data)
{
    VncState *vs = container_of(notifier, VncState, cbpeer.notifier);
    QemuClipboardNotify *notify = data;

    switch (notify->type) {
    case QEMU_CLIPBOARD_UPDATE_INFO:
        vnc_clipboard_update_info(vs, notify->info);
        return;
    case QEMU_CLIPBOARD_RESET_SERIAL:
        /* ignore */
        return;
    }
}

static void vnc_clipboard_request(QemuClipboardInfo *info,
                                  QemuClipboardType type)
{
    VncState *vs = container_of(info->owner, VncState, cbpeer);
    uint32_t flags = 0;

    if (type == QEMU_CLIPBOARD_TYPE_TEXT) {
        flags |= VNC_CLIPBOARD_TEXT;
    }
    if (!flags) {
        return;
    }
    flags |= VNC_CLIPBOARD_REQUEST;

    vnc_clipboard_send(vs, 1, &flags);
}

void vnc_client_cut_text_ext(VncState *vs, int32_t len, uint32_t flags, uint8_t *data)
{
    if (flags & VNC_CLIPBOARD_CAPS) {
        /* need store caps somewhere ? */
        return;
    }

    if (flags & VNC_CLIPBOARD_NOTIFY) {
        QemuClipboardInfo *info =
            qemu_clipboard_info_new(&vs->cbpeer, QEMU_CLIPBOARD_SELECTION_CLIPBOARD);
        if (flags & VNC_CLIPBOARD_TEXT) {
            info->types[QEMU_CLIPBOARD_TYPE_TEXT].available = true;
        }
        qemu_clipboard_update(info);
        qemu_clipboard_info_unref(info);
        return;
    }

    if (flags & VNC_CLIPBOARD_PROVIDE &&
        vs->cbinfo &&
        vs->cbinfo->owner == &vs->cbpeer) {
        uint32_t size = 0;
        g_autofree uint8_t *buf = inflate_buffer(data, len - 4, &size);
        if ((flags & VNC_CLIPBOARD_TEXT) &&
            buf && size >= 4) {
            uint32_t tsize = read_u32(buf, 0);
            uint8_t *tbuf = buf + 4;
            if (tsize < size) {
                qemu_clipboard_set_data(&vs->cbpeer, vs->cbinfo,
                                        QEMU_CLIPBOARD_TYPE_TEXT,
                                        tsize, tbuf, true);
            }
        }
    }

    if (flags & VNC_CLIPBOARD_REQUEST &&
        vs->cbinfo &&
        vs->cbinfo->owner != &vs->cbpeer) {
        if ((flags & VNC_CLIPBOARD_TEXT) &&
            vs->cbinfo->types[QEMU_CLIPBOARD_TYPE_TEXT].available) {
            if (vs->cbinfo->types[QEMU_CLIPBOARD_TYPE_TEXT].data) {
                vnc_clipboard_provide(vs, vs->cbinfo, QEMU_CLIPBOARD_TYPE_TEXT);
            } else {
                vs->cbpending |= (1 << QEMU_CLIPBOARD_TYPE_TEXT);
                qemu_clipboard_request(vs->cbinfo, QEMU_CLIPBOARD_TYPE_TEXT);
            }
        }
    }
}

void vnc_client_cut_text(VncState *vs, size_t len, uint8_t *text)
{
    QemuClipboardInfo *info =
        qemu_clipboard_info_new(&vs->cbpeer, QEMU_CLIPBOARD_SELECTION_CLIPBOARD);

    qemu_clipboard_set_data(&vs->cbpeer, info, QEMU_CLIPBOARD_TYPE_TEXT,
                            len, text, true);
    qemu_clipboard_info_unref(info);
}

void vnc_server_cut_text_caps(VncState *vs)
{
    uint32_t caps[2];

    if (!vnc_has_feature(vs, VNC_FEATURE_CLIPBOARD_EXT)) {
        return;
    }

    caps[0] = (VNC_CLIPBOARD_PROVIDE |
               VNC_CLIPBOARD_NOTIFY  |
               VNC_CLIPBOARD_REQUEST |
               VNC_CLIPBOARD_CAPS    |
               VNC_CLIPBOARD_TEXT);
    caps[1] = 0;
    vnc_clipboard_send(vs, 2, caps);

    if (!vs->cbpeer.notifier.notify) {
        vs->cbpeer.name = "vnc";
        vs->cbpeer.notifier.notify = vnc_clipboard_notify;
        vs->cbpeer.request = vnc_clipboard_request;
        qemu_clipboard_peer_register(&vs->cbpeer);
    }
}
