/*
 * QEMU DBus audio
 *
 * Copyright (c) 2021 Red Hat, Inc.
 *
 * 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/error-report.h"
#include "qemu/host-utils.h"
#include "qemu/module.h"
#include "qemu/timer.h"
#include "qemu/dbus.h"

#include <gio/gunixfdlist.h>
#include "ui/dbus-display1.h"

#define AUDIO_CAP "dbus"
#include "audio.h"
#include "audio_int.h"
#include "trace.h"

#define DBUS_DISPLAY1_AUDIO_PATH DBUS_DISPLAY1_ROOT "/Audio"

#define DBUS_AUDIO_NSAMPLES 1024 /* could be configured? */

typedef struct DBusAudio {
    GDBusObjectManagerServer *server;
    GDBusObjectSkeleton *audio;
    QemuDBusDisplay1Audio *iface;
    GHashTable *out_listeners;
    GHashTable *in_listeners;
} DBusAudio;

typedef struct DBusVoiceOut {
    HWVoiceOut hw;
    bool enabled;
    RateCtl rate;

    void *buf;
    size_t buf_pos;
    size_t buf_size;

    bool has_volume;
    Volume volume;
} DBusVoiceOut;

typedef struct DBusVoiceIn {
    HWVoiceIn hw;
    bool enabled;
    RateCtl rate;

    bool has_volume;
    Volume volume;
} DBusVoiceIn;

static void *dbus_get_buffer_out(HWVoiceOut *hw, size_t *size)
{
    DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);

    if (!vo->buf) {
        vo->buf_size = hw->samples * hw->info.bytes_per_frame;
        vo->buf = g_malloc(vo->buf_size);
        vo->buf_pos = 0;
    }

    *size = MIN(vo->buf_size - vo->buf_pos, *size);
    *size = audio_rate_get_bytes(&hw->info, &vo->rate, *size);

    return vo->buf + vo->buf_pos;

}

static size_t dbus_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size)
{
    DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
    DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
    GHashTableIter iter;
    QemuDBusDisplay1AudioOutListener *listener = NULL;
    g_autoptr(GBytes) bytes = NULL;
    g_autoptr(GVariant) v_data = NULL;

    assert(buf == vo->buf + vo->buf_pos && vo->buf_pos + size <= vo->buf_size);
    vo->buf_pos += size;

    trace_dbus_audio_put_buffer_out(size);

    if (vo->buf_pos < vo->buf_size) {
        return size;
    }

    bytes = g_bytes_new_take(g_steal_pointer(&vo->buf), vo->buf_size);
    v_data = g_variant_new_from_bytes(G_VARIANT_TYPE("ay"), bytes, TRUE);
    g_variant_ref_sink(v_data);

    g_hash_table_iter_init(&iter, da->out_listeners);
    while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
        qemu_dbus_display1_audio_out_listener_call_write(
            listener,
            (uintptr_t)hw,
            v_data,
            G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
    }

    return size;
}

#ifdef HOST_WORDS_BIGENDIAN
#define AUDIO_HOST_BE TRUE
#else
#define AUDIO_HOST_BE FALSE
#endif

static void
dbus_init_out_listener(QemuDBusDisplay1AudioOutListener *listener,
                       HWVoiceOut *hw)
{
    qemu_dbus_display1_audio_out_listener_call_init(
        listener,
        (uintptr_t)hw,
        hw->info.bits,
        hw->info.is_signed,
        hw->info.is_float,
        hw->info.freq,
        hw->info.nchannels,
        hw->info.bytes_per_frame,
        hw->info.bytes_per_second,
        hw->info.swap_endianness ? !AUDIO_HOST_BE : AUDIO_HOST_BE,
        G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
}

static int
dbus_init_out(HWVoiceOut *hw, struct audsettings *as, void *drv_opaque)
{
    DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
    DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
    GHashTableIter iter;
    QemuDBusDisplay1AudioOutListener *listener = NULL;

    audio_pcm_init_info(&hw->info, as);
    hw->samples = DBUS_AUDIO_NSAMPLES;
    audio_rate_start(&vo->rate);

    g_hash_table_iter_init(&iter, da->out_listeners);
    while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
        dbus_init_out_listener(listener, hw);
    }
    return 0;
}

static void
dbus_fini_out(HWVoiceOut *hw)
{
    DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
    DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
    GHashTableIter iter;
    QemuDBusDisplay1AudioOutListener *listener = NULL;

    g_hash_table_iter_init(&iter, da->out_listeners);
    while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
        qemu_dbus_display1_audio_out_listener_call_fini(
            listener,
            (uintptr_t)hw,
            G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
    }

    g_clear_pointer(&vo->buf, g_free);
}

static void
dbus_enable_out(HWVoiceOut *hw, bool enable)
{
    DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
    DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
    GHashTableIter iter;
    QemuDBusDisplay1AudioOutListener *listener = NULL;

    vo->enabled = enable;
    if (enable) {
        audio_rate_start(&vo->rate);
    }

    g_hash_table_iter_init(&iter, da->out_listeners);
    while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
        qemu_dbus_display1_audio_out_listener_call_set_enabled(
            listener, (uintptr_t)hw, enable,
            G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
    }
}

static void
dbus_volume_out_listener(HWVoiceOut *hw,
                         QemuDBusDisplay1AudioOutListener *listener)
{
    DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
    Volume *vol = &vo->volume;
    g_autoptr(GBytes) bytes = NULL;
    GVariant *v_vol = NULL;

    if (!vo->has_volume) {
        return;
    }

    assert(vol->channels < sizeof(vol->vol));
    bytes = g_bytes_new(vol->vol, vol->channels);
    v_vol = g_variant_new_from_bytes(G_VARIANT_TYPE("ay"), bytes, TRUE);
    qemu_dbus_display1_audio_out_listener_call_set_volume(
        listener, (uintptr_t)hw, vol->mute, v_vol,
        G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
}

static void
dbus_volume_out(HWVoiceOut *hw, Volume *vol)
{
    DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
    DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
    GHashTableIter iter;
    QemuDBusDisplay1AudioOutListener *listener = NULL;

    vo->has_volume = true;
    vo->volume = *vol;

    g_hash_table_iter_init(&iter, da->out_listeners);
    while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
        dbus_volume_out_listener(hw, listener);
    }
}

static void
dbus_init_in_listener(QemuDBusDisplay1AudioInListener *listener, HWVoiceIn *hw)
{
    qemu_dbus_display1_audio_in_listener_call_init(
        listener,
        (uintptr_t)hw,
        hw->info.bits,
        hw->info.is_signed,
        hw->info.is_float,
        hw->info.freq,
        hw->info.nchannels,
        hw->info.bytes_per_frame,
        hw->info.bytes_per_second,
        hw->info.swap_endianness ? !AUDIO_HOST_BE : AUDIO_HOST_BE,
        G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
}

static int
dbus_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
{
    DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
    DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw);
    GHashTableIter iter;
    QemuDBusDisplay1AudioInListener *listener = NULL;

    audio_pcm_init_info(&hw->info, as);
    hw->samples = DBUS_AUDIO_NSAMPLES;
    audio_rate_start(&vo->rate);

    g_hash_table_iter_init(&iter, da->in_listeners);
    while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
        dbus_init_in_listener(listener, hw);
    }
    return 0;
}

static void
dbus_fini_in(HWVoiceIn *hw)
{
    DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
    GHashTableIter iter;
    QemuDBusDisplay1AudioInListener *listener = NULL;

    g_hash_table_iter_init(&iter, da->in_listeners);
    while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
        qemu_dbus_display1_audio_in_listener_call_fini(
            listener,
            (uintptr_t)hw,
            G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
    }
}

static void
dbus_volume_in_listener(HWVoiceIn *hw,
                         QemuDBusDisplay1AudioInListener *listener)
{
    DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw);
    Volume *vol = &vo->volume;
    g_autoptr(GBytes) bytes = NULL;
    GVariant *v_vol = NULL;

    if (!vo->has_volume) {
        return;
    }

    assert(vol->channels < sizeof(vol->vol));
    bytes = g_bytes_new(vol->vol, vol->channels);
    v_vol = g_variant_new_from_bytes(G_VARIANT_TYPE("ay"), bytes, TRUE);
    qemu_dbus_display1_audio_in_listener_call_set_volume(
        listener, (uintptr_t)hw, vol->mute, v_vol,
        G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
}

static void
dbus_volume_in(HWVoiceIn *hw, Volume *vol)
{
    DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
    DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw);
    GHashTableIter iter;
    QemuDBusDisplay1AudioInListener *listener = NULL;

    vo->has_volume = true;
    vo->volume = *vol;

    g_hash_table_iter_init(&iter, da->in_listeners);
    while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
        dbus_volume_in_listener(hw, listener);
    }
}

static size_t
dbus_read(HWVoiceIn *hw, void *buf, size_t size)
{
    DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
    /* DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw); */
    GHashTableIter iter;
    QemuDBusDisplay1AudioInListener *listener = NULL;

    trace_dbus_audio_read(size);

    /* size = audio_rate_get_bytes(&hw->info, &vo->rate, size); */

    g_hash_table_iter_init(&iter, da->in_listeners);
    while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
        g_autoptr(GVariant) v_data = NULL;
        const char *data;
        gsize n = 0;

        if (qemu_dbus_display1_audio_in_listener_call_read_sync(
                listener,
                (uintptr_t)hw,
                size,
                G_DBUS_CALL_FLAGS_NONE, -1,
                &v_data, NULL, NULL)) {
            data = g_variant_get_fixed_array(v_data, &n, 1);
            g_warn_if_fail(n <= size);
            size = MIN(n, size);
            memcpy(buf, data, size);
            break;
        }
    }

    return size;
}

static void
dbus_enable_in(HWVoiceIn *hw, bool enable)
{
    DBusAudio *da = (DBusAudio *)hw->s->drv_opaque;
    DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw);
    GHashTableIter iter;
    QemuDBusDisplay1AudioInListener *listener = NULL;

    vo->enabled = enable;
    if (enable) {
        audio_rate_start(&vo->rate);
    }

    g_hash_table_iter_init(&iter, da->in_listeners);
    while (g_hash_table_iter_next(&iter, NULL, (void **)&listener)) {
        qemu_dbus_display1_audio_in_listener_call_set_enabled(
            listener, (uintptr_t)hw, enable,
            G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
    }
}

static void *
dbus_audio_init(Audiodev *dev)
{
    DBusAudio *da = g_new0(DBusAudio, 1);

    da->out_listeners = g_hash_table_new_full(g_str_hash, g_str_equal,
                                                g_free, g_object_unref);
    da->in_listeners = g_hash_table_new_full(g_str_hash, g_str_equal,
                                               g_free, g_object_unref);
    return da;
}

static void
dbus_audio_fini(void *opaque)
{
    DBusAudio *da = opaque;

    if (da->server) {
        g_dbus_object_manager_server_unexport(da->server,
                                              DBUS_DISPLAY1_AUDIO_PATH);
    }
    g_clear_object(&da->audio);
    g_clear_object(&da->iface);
    g_clear_pointer(&da->in_listeners, g_hash_table_unref);
    g_clear_pointer(&da->out_listeners, g_hash_table_unref);
    g_clear_object(&da->server);
    g_free(da);
}

static void
listener_out_vanished_cb(GDBusConnection *connection,
                         gboolean remote_peer_vanished,
                         GError *error,
                         DBusAudio *da)
{
    char *name = g_object_get_data(G_OBJECT(connection), "name");

    g_hash_table_remove(da->out_listeners, name);
}

static void
listener_in_vanished_cb(GDBusConnection *connection,
                        gboolean remote_peer_vanished,
                        GError *error,
                        DBusAudio *da)
{
    char *name = g_object_get_data(G_OBJECT(connection), "name");

    g_hash_table_remove(da->in_listeners, name);
}

static gboolean
dbus_audio_register_listener(AudioState *s,
                             GDBusMethodInvocation *invocation,
                             GUnixFDList *fd_list,
                             GVariant *arg_listener,
                             bool out)
{
    DBusAudio *da = s->drv_opaque;
    const char *sender = g_dbus_method_invocation_get_sender(invocation);
    g_autoptr(GDBusConnection) listener_conn = NULL;
    g_autoptr(GError) err = NULL;
    g_autoptr(GSocket) socket = NULL;
    g_autoptr(GSocketConnection) socket_conn = NULL;
    g_autofree char *guid = g_dbus_generate_guid();
    GHashTable *listeners = out ? da->out_listeners : da->in_listeners;
    GObject *listener;
    int fd;

    trace_dbus_audio_register(sender, out ? "out" : "in");

    if (g_hash_table_contains(listeners, sender)) {
        g_dbus_method_invocation_return_error(invocation,
                                              DBUS_DISPLAY_ERROR,
                                              DBUS_DISPLAY_ERROR_INVALID,
                                              "`%s` is already registered!",
                                              sender);
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    fd = g_unix_fd_list_get(fd_list, g_variant_get_handle(arg_listener), &err);
    if (err) {
        g_dbus_method_invocation_return_error(invocation,
                                              DBUS_DISPLAY_ERROR,
                                              DBUS_DISPLAY_ERROR_FAILED,
                                              "Couldn't get peer fd: %s",
                                              err->message);
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    socket = g_socket_new_from_fd(fd, &err);
    if (err) {
        g_dbus_method_invocation_return_error(invocation,
                                              DBUS_DISPLAY_ERROR,
                                              DBUS_DISPLAY_ERROR_FAILED,
                                              "Couldn't make a socket: %s",
                                              err->message);
        return DBUS_METHOD_INVOCATION_HANDLED;
    }
    socket_conn = g_socket_connection_factory_create_connection(socket);
    if (out) {
        qemu_dbus_display1_audio_complete_register_out_listener(
            da->iface, invocation, NULL);
    } else {
        qemu_dbus_display1_audio_complete_register_in_listener(
            da->iface, invocation, NULL);
    }

    listener_conn =
        g_dbus_connection_new_sync(
            G_IO_STREAM(socket_conn),
            guid,
            G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_SERVER,
            NULL, NULL, &err);
    if (err) {
        error_report("Failed to setup peer connection: %s", err->message);
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    listener = out ?
        G_OBJECT(qemu_dbus_display1_audio_out_listener_proxy_new_sync(
            listener_conn,
            G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
            NULL,
            "/org/qemu/Display1/AudioOutListener",
            NULL,
            &err)) :
        G_OBJECT(qemu_dbus_display1_audio_in_listener_proxy_new_sync(
            listener_conn,
            G_DBUS_PROXY_FLAGS_DO_NOT_AUTO_START,
            NULL,
            "/org/qemu/Display1/AudioInListener",
            NULL,
            &err));
    if (!listener) {
        error_report("Failed to setup proxy: %s", err->message);
        return DBUS_METHOD_INVOCATION_HANDLED;
    }

    if (out) {
        HWVoiceOut *hw;

        QLIST_FOREACH(hw, &s->hw_head_out, entries) {
            DBusVoiceOut *vo = container_of(hw, DBusVoiceOut, hw);
            QemuDBusDisplay1AudioOutListener *l =
                QEMU_DBUS_DISPLAY1_AUDIO_OUT_LISTENER(listener);

            dbus_init_out_listener(l, hw);
            qemu_dbus_display1_audio_out_listener_call_set_enabled(
                l, (uintptr_t)hw, vo->enabled,
                G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
        }
    } else {
        HWVoiceIn *hw;

        QLIST_FOREACH(hw, &s->hw_head_in, entries) {
            DBusVoiceIn *vo = container_of(hw, DBusVoiceIn, hw);
            QemuDBusDisplay1AudioInListener *l =
                QEMU_DBUS_DISPLAY1_AUDIO_IN_LISTENER(listener);

            dbus_init_in_listener(
                QEMU_DBUS_DISPLAY1_AUDIO_IN_LISTENER(listener), hw);
            qemu_dbus_display1_audio_in_listener_call_set_enabled(
                l, (uintptr_t)hw, vo->enabled,
                G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);
        }
    }

    g_object_set_data_full(G_OBJECT(listener_conn), "name",
                           g_strdup(sender), g_free);
    g_hash_table_insert(listeners, g_strdup(sender), listener);
    g_object_connect(listener_conn,
                     "signal::closed",
                     out ? listener_out_vanished_cb : listener_in_vanished_cb,
                     da,
                     NULL);

    return DBUS_METHOD_INVOCATION_HANDLED;
}

static gboolean
dbus_audio_register_out_listener(AudioState *s,
                                 GDBusMethodInvocation *invocation,
                                 GUnixFDList *fd_list,
                                 GVariant *arg_listener)
{
    return dbus_audio_register_listener(s, invocation,
                                        fd_list, arg_listener, true);

}

static gboolean
dbus_audio_register_in_listener(AudioState *s,
                                GDBusMethodInvocation *invocation,
                                GUnixFDList *fd_list,
                                GVariant *arg_listener)
{
    return dbus_audio_register_listener(s, invocation,
                                        fd_list, arg_listener, false);
}

static void
dbus_audio_set_server(AudioState *s, GDBusObjectManagerServer *server)
{
    DBusAudio *da = s->drv_opaque;

    g_assert(da);
    g_assert(!da->server);

    da->server = g_object_ref(server);

    da->audio = g_dbus_object_skeleton_new(DBUS_DISPLAY1_AUDIO_PATH);
    da->iface = qemu_dbus_display1_audio_skeleton_new();
    g_object_connect(da->iface,
                     "swapped-signal::handle-register-in-listener",
                     dbus_audio_register_in_listener, s,
                     "swapped-signal::handle-register-out-listener",
                     dbus_audio_register_out_listener, s,
                     NULL);

    g_dbus_object_skeleton_add_interface(G_DBUS_OBJECT_SKELETON(da->audio),
                                         G_DBUS_INTERFACE_SKELETON(da->iface));
    g_dbus_object_manager_server_export(da->server, da->audio);
}

static struct audio_pcm_ops dbus_pcm_ops = {
    .init_out = dbus_init_out,
    .fini_out = dbus_fini_out,
    .write    = audio_generic_write,
    .get_buffer_out = dbus_get_buffer_out,
    .put_buffer_out = dbus_put_buffer_out,
    .enable_out = dbus_enable_out,
    .volume_out = dbus_volume_out,

    .init_in  = dbus_init_in,
    .fini_in  = dbus_fini_in,
    .read     = dbus_read,
    .run_buffer_in = audio_generic_run_buffer_in,
    .enable_in = dbus_enable_in,
    .volume_in = dbus_volume_in,
};

static struct audio_driver dbus_audio_driver = {
    .name            = "dbus",
    .descr           = "Timer based audio exposed with DBus interface",
    .init            = dbus_audio_init,
    .fini            = dbus_audio_fini,
    .set_dbus_server = dbus_audio_set_server,
    .pcm_ops         = &dbus_pcm_ops,
    .can_be_default  = 1,
    .max_voices_out  = INT_MAX,
    .max_voices_in   = INT_MAX,
    .voice_size_out  = sizeof(DBusVoiceOut),
    .voice_size_in   = sizeof(DBusVoiceIn)
};

static void register_audio_dbus(void)
{
    audio_driver_register(&dbus_audio_driver);
}
type_init(register_audio_dbus);

module_dep("ui-dbus")
