/*
 * QEMU external Spice client display driver
 *
 * Copyright (c) 2018 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 <gio/gio.h>

#include "qemu-common.h"
#include "ui/console.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "qemu/cutils.h"
#include "qapi/error.h"
#include "io/channel-command.h"
#include "chardev/spice.h"
#include "sysemu/sysemu.h"

static const char *tmp_dir;
static char *app_dir;
static char *sock_path;

typedef struct VCChardev {
    SpiceChardev parent;
} VCChardev;

#define TYPE_CHARDEV_VC "chardev-vc"
#define VC_CHARDEV(obj) OBJECT_CHECK(VCChardev, (obj), TYPE_CHARDEV_VC)

static ChardevBackend *
chr_spice_backend_new(void)
{
    ChardevBackend *be = g_new0(ChardevBackend, 1);

    be->type = CHARDEV_BACKEND_KIND_SPICEPORT;
    be->u.spiceport.data = g_new0(ChardevSpicePort, 1);

    return be;
}

static void vc_chr_open(Chardev *chr,
                        ChardevBackend *backend,
                        bool *be_opened,
                        Error **errp)
{
    ChardevBackend *be;
    const char *fqdn = NULL;

    if (strstart(chr->label, "serial", NULL)) {
        fqdn = "org.qemu.console.serial.0";
    } else if (strstart(chr->label, "parallel", NULL)) {
        fqdn = "org.qemu.console.parallel.0";
    } else if (strstart(chr->label, "compat_monitor", NULL)) {
        fqdn = "org.qemu.monitor.hmp.0";
    }

    be = chr_spice_backend_new();
    be->u.spiceport.data->fqdn = fqdn ?
        g_strdup(fqdn) : g_strdup_printf("org.qemu.console.%s", chr->label);
    qemu_chr_open_spice_port(chr, be, be_opened, errp);
    qapi_free_ChardevBackend(be);
}

static void vc_chr_set_echo(Chardev *chr, bool echo)
{
    /* TODO: set echo for frontends QMP and qtest */
}

static void char_vc_class_init(ObjectClass *oc, void *data)
{
    ChardevClass *cc = CHARDEV_CLASS(oc);

    cc->parse = qemu_chr_parse_vc;
    cc->open = vc_chr_open;
    cc->chr_set_echo = vc_chr_set_echo;
}

static const TypeInfo char_vc_type_info = {
    .name = TYPE_CHARDEV_VC,
    .parent = TYPE_CHARDEV_SPICEPORT,
    .instance_size = sizeof(VCChardev),
    .class_init = char_vc_class_init,
};

static void spice_app_atexit(void)
{
    if (sock_path) {
        unlink(sock_path);
    }
    if (tmp_dir) {
        rmdir(tmp_dir);
    }
    g_free(sock_path);
    g_free(app_dir);
}

static void spice_app_display_early_init(DisplayOptions *opts)
{
    QemuOpts *qopts;
    ChardevBackend *be = chr_spice_backend_new();
    GError *err = NULL;

    if (opts->has_full_screen) {
        error_report("spice-app full-screen isn't supported yet.");
        exit(1);
    }
    if (opts->has_window_close) {
        error_report("spice-app window-close isn't supported yet.");
        exit(1);
    }

    atexit(spice_app_atexit);

    if (qemu_name) {
        app_dir = g_build_filename(g_get_user_runtime_dir(),
                                   "qemu", qemu_name, NULL);
        if (g_mkdir_with_parents(app_dir, S_IRWXU) < -1) {
            error_report("Failed to create directory %s: %s",
                         app_dir, strerror(errno));
            exit(1);
        }
    } else {
        app_dir = g_dir_make_tmp(NULL, &err);
        tmp_dir = app_dir;
        if (err) {
            error_report("Failed to create temporary directory: %s",
                         err->message);
            exit(1);
        }
    }

    type_register(&char_vc_type_info);

    sock_path = g_strjoin("", app_dir, "/", "spice.sock", NULL);
    qopts = qemu_opts_create(qemu_find_opts("spice"), NULL, 0, &error_abort);
    qemu_opt_set(qopts, "disable-ticketing", "on", &error_abort);
    qemu_opt_set(qopts, "unix", "on", &error_abort);
    qemu_opt_set(qopts, "addr", sock_path, &error_abort);
    qemu_opt_set(qopts, "image-compression", "off", &error_abort);
    qemu_opt_set(qopts, "streaming-video", "off", &error_abort);
    qemu_opt_set(qopts, "gl", opts->has_gl ? "on" : "off", &error_abort);
    display_opengl = opts->has_gl;

    be->u.spiceport.data->fqdn = g_strdup("org.qemu.monitor.qmp.0");
    qemu_chardev_new("org.qemu.monitor.qmp", TYPE_CHARDEV_SPICEPORT,
                     be, NULL, &error_abort);
    qopts = qemu_opts_create(qemu_find_opts("mon"),
                             NULL, 0, &error_fatal);
    qemu_opt_set(qopts, "chardev", "org.qemu.monitor.qmp", &error_abort);
    qemu_opt_set(qopts, "mode", "control", &error_abort);

    qapi_free_ChardevBackend(be);
}

static void spice_app_display_init(DisplayState *ds, DisplayOptions *opts)
{
    GError *err = NULL;
    gchar *uri;

    uri = g_strjoin("", "spice+unix://", app_dir, "/", "spice.sock", NULL);
    info_report("Launching display with URI: %s", uri);
    g_app_info_launch_default_for_uri(uri, NULL, &err);
    if (err) {
        error_report("Failed to launch %s URI: %s", uri, err->message);
        error_report("You need a capable Spice client, "
                     "such as virt-viewer 8.0");
        exit(1);
    }
    g_free(uri);
}

static QemuDisplay qemu_display_spice_app = {
    .type       = DISPLAY_TYPE_SPICE_APP,
    .early_init = spice_app_display_early_init,
    .init       = spice_app_display_init,
};

static void register_spice_app(void)
{
    qemu_display_register(&qemu_display_spice_app);
}

type_init(register_spice_app);
