/*
 * 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 "ui/console.h"
#include "ui/spice-display.h"
#include "qemu/config-file.h"
#include "qemu/option.h"
#include "qemu/cutils.h"
#include "qemu/module.h"
#include "qapi/error.h"
#include "io/channel-command.h"
#include "chardev/spice.h"
#include "sysemu/sysemu.h"
#include "qom/object.h"

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

struct VCChardev {
    SpiceChardev parent;
};

struct VCChardevClass {
    ChardevClass parent;
    void (*parent_open)(Chardev *chr, ChardevBackend *backend,
                        bool *be_opened, Error **errp);
};

#define TYPE_CHARDEV_VC "chardev-vc"
OBJECT_DECLARE_TYPE(VCChardev, VCChardevClass, 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)
{
    VCChardevClass *vc = CHARDEV_VC_GET_CLASS(chr);
    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);
    vc->parent_open(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)
{
    VCChardevClass *vc = CHARDEV_VC_CLASS(oc);
    ChardevClass *cc = CHARDEV_CLASS(oc);

    vc->parent_open = cc->open;

    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,
    .class_size = sizeof(VCChardevClass),
};

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;
    QemuOptsList *list;
    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);
        }
    }
    list = qemu_find_opts("spice");
    if (list == NULL) {
        error_report("spice-app missing spice support");
        exit(1);
    }

    type_register(&char_vc_type_info);

    sock_path = g_strjoin("", app_dir, "/", "spice.sock", NULL);
    qopts = qemu_opts_create(list, 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);
#ifdef HAVE_SPICE_GL
    qemu_opt_set(qopts, "gl", opts->has_gl ? "on" : "off", &error_abort);
    display_opengl = opts->has_gl;
#endif
}

static void spice_app_display_init(DisplayState *ds, DisplayOptions *opts)
{
    ChardevBackend *be = chr_spice_backend_new();
    QemuOpts *qopts;
    GError *err = NULL;
    gchar *uri;

    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);
    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);

module_dep("ui-spice-core");
module_dep("chardev-spice");
