/*
 * 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;
}

#if HOST_BIG_ENDIAN
#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")
