/*
 * QEMU VNC display driver: Websockets support
 *
 * Copyright (C) 2010 Joel Martin
 * Copyright (C) 2012 Tim Hardeck
 *
 * This 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 software 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 software; if not, see <http://www.gnu.org/licenses/>.
 */

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "vnc.h"
#include "io/channel-websock.h"
#include "qemu/bswap.h"

static void vncws_tls_handshake_done(Object *source,
                                     Error *err,
                                     gpointer user_data)
{
    VncState *vs = user_data;

    if (err) {
        VNC_DEBUG("Handshake failed %s\n", error_get_pretty(err));
        vnc_client_error(vs);
    } else {
        VNC_DEBUG("TLS handshake complete, starting websocket handshake\n");
        vs->ioc_tag = qio_channel_add_watch(
            QIO_CHANNEL(vs->ioc), G_IO_IN, vncws_handshake_io, vs, NULL);
    }
}


gboolean vncws_tls_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
                                GIOCondition condition G_GNUC_UNUSED,
                                void *opaque)
{
    VncState *vs = opaque;
    QIOChannelTLS *tls;
    Error *err = NULL;

    VNC_DEBUG("TLS Websocket connection required\n");
    if (vs->ioc_tag) {
        g_source_remove(vs->ioc_tag);
        vs->ioc_tag = 0;
    }

    tls = qio_channel_tls_new_server(
        vs->ioc,
        vs->vd->tlscreds,
        vs->vd->tlsaclname,
        &err);
    if (!tls) {
        VNC_DEBUG("Failed to setup TLS %s\n", error_get_pretty(err));
        error_free(err);
        vnc_client_error(vs);
        return TRUE;
    }

    qio_channel_set_name(QIO_CHANNEL(tls), "vnc-ws-server-tls");

    VNC_DEBUG("Start TLS WS handshake process\n");
    object_unref(OBJECT(vs->ioc));
    vs->ioc = QIO_CHANNEL(tls);
    vs->tls = qio_channel_tls_get_session(tls);

    qio_channel_tls_handshake(tls,
                              vncws_tls_handshake_done,
                              vs,
                              NULL);

    return TRUE;
}


static void vncws_handshake_done(Object *source,
                                 Error *err,
                                 gpointer user_data)
{
    VncState *vs = user_data;

    if (err) {
        VNC_DEBUG("Websock handshake failed %s\n", error_get_pretty(err));
        vnc_client_error(vs);
    } else {
        VNC_DEBUG("Websock handshake complete, starting VNC protocol\n");
        vnc_start_protocol(vs);
        vs->ioc_tag = qio_channel_add_watch(
            vs->ioc, G_IO_IN, vnc_client_io, vs, NULL);
    }
}


gboolean vncws_handshake_io(QIOChannel *ioc G_GNUC_UNUSED,
                            GIOCondition condition G_GNUC_UNUSED,
                            void *opaque)
{
    VncState *vs = opaque;
    QIOChannelWebsock *wioc;

    VNC_DEBUG("Websocket negotiate starting\n");
    if (vs->ioc_tag) {
        g_source_remove(vs->ioc_tag);
        vs->ioc_tag = 0;
    }

    wioc = qio_channel_websock_new_server(vs->ioc);
    qio_channel_set_name(QIO_CHANNEL(wioc), "vnc-ws-server-websock");

    object_unref(OBJECT(vs->ioc));
    vs->ioc = QIO_CHANNEL(wioc);

    qio_channel_websock_handshake(wioc,
                                  vncws_handshake_done,
                                  vs,
                                  NULL);

    return TRUE;
}
