/* public domain */

#include "qemu/osdep.h"
#include "qemu/module.h"
#include "audio.h"
#include "qapi/opts-visitor.h"

#include <pulse/pulseaudio.h>

#define AUDIO_CAP "pulseaudio"
#include "audio_int.h"

typedef struct PAConnection {
    char *server;
    int refcount;
    QTAILQ_ENTRY(PAConnection) list;

    pa_threaded_mainloop *mainloop;
    pa_context *context;
} PAConnection;

static QTAILQ_HEAD(PAConnectionHead, PAConnection) pa_conns =
    QTAILQ_HEAD_INITIALIZER(pa_conns);

typedef struct {
    Audiodev *dev;
    PAConnection *conn;
} paaudio;

typedef struct {
    HWVoiceOut hw;
    pa_stream *stream;
    paaudio *g;
} PAVoiceOut;

typedef struct {
    HWVoiceIn hw;
    pa_stream *stream;
    const void *read_data;
    size_t read_length;
    paaudio *g;
} PAVoiceIn;

static void qpa_conn_fini(PAConnection *c);

static void GCC_FMT_ATTR (2, 3) qpa_logerr (int err, const char *fmt, ...)
{
    va_list ap;

    va_start (ap, fmt);
    AUD_vlog (AUDIO_CAP, fmt, ap);
    va_end (ap);

    AUD_log (AUDIO_CAP, "Reason: %s\n", pa_strerror (err));
}

#ifndef PA_CONTEXT_IS_GOOD
static inline int PA_CONTEXT_IS_GOOD(pa_context_state_t x)
{
    return
        x == PA_CONTEXT_CONNECTING ||
        x == PA_CONTEXT_AUTHORIZING ||
        x == PA_CONTEXT_SETTING_NAME ||
        x == PA_CONTEXT_READY;
}
#endif

#ifndef PA_STREAM_IS_GOOD
static inline int PA_STREAM_IS_GOOD(pa_stream_state_t x)
{
    return
        x == PA_STREAM_CREATING ||
        x == PA_STREAM_READY;
}
#endif

#define CHECK_SUCCESS_GOTO(c, expression, label, msg)           \
    do {                                                        \
        if (!(expression)) {                                    \
            qpa_logerr(pa_context_errno((c)->context), msg);    \
            goto label;                                         \
        }                                                       \
    } while (0)

#define CHECK_DEAD_GOTO(c, stream, label, msg)                          \
    do {                                                                \
        if (!(c)->context || !PA_CONTEXT_IS_GOOD (pa_context_get_state((c)->context)) || \
            !(stream) || !PA_STREAM_IS_GOOD (pa_stream_get_state ((stream)))) { \
            if (((c)->context && pa_context_get_state ((c)->context) == PA_CONTEXT_FAILED) || \
                ((stream) && pa_stream_get_state ((stream)) == PA_STREAM_FAILED)) { \
                qpa_logerr(pa_context_errno((c)->context), msg);        \
            } else {                                                    \
                qpa_logerr(PA_ERR_BADSTATE, msg);                       \
            }                                                           \
            goto label;                                                 \
        }                                                               \
    } while (0)

static void *qpa_get_buffer_in(HWVoiceIn *hw, size_t *size)
{
    PAVoiceIn *p = (PAVoiceIn *) hw;
    PAConnection *c = p->g->conn;
    int r;

    pa_threaded_mainloop_lock(c->mainloop);

    CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
                    "pa_threaded_mainloop_lock failed\n");

    if (!p->read_length) {
        r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
        CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
                           "pa_stream_peek failed\n");
    }

    *size = MIN(p->read_length, *size);

    pa_threaded_mainloop_unlock(c->mainloop);
    return (void *) p->read_data;

unlock_and_fail:
    pa_threaded_mainloop_unlock(c->mainloop);
    *size = 0;
    return NULL;
}

static void qpa_put_buffer_in(HWVoiceIn *hw, void *buf, size_t size)
{
    PAVoiceIn *p = (PAVoiceIn *) hw;
    PAConnection *c = p->g->conn;
    int r;

    pa_threaded_mainloop_lock(c->mainloop);

    CHECK_DEAD_GOTO(c, p->stream, unlock,
                    "pa_threaded_mainloop_lock failed\n");

    assert(buf == p->read_data && size <= p->read_length);

    p->read_data += size;
    p->read_length -= size;

    if (size && !p->read_length) {
        r = pa_stream_drop(p->stream);
        CHECK_SUCCESS_GOTO(c, r == 0, unlock, "pa_stream_drop failed\n");
    }

unlock:
    pa_threaded_mainloop_unlock(c->mainloop);
}

static size_t qpa_read(HWVoiceIn *hw, void *data, size_t length)
{
    PAVoiceIn *p = (PAVoiceIn *) hw;
    PAConnection *c = p->g->conn;
    size_t total = 0;

    pa_threaded_mainloop_lock(c->mainloop);

    CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
                    "pa_threaded_mainloop_lock failed\n");
    if (pa_stream_get_state(p->stream) != PA_STREAM_READY) {
        /* wait for stream to become ready */
        goto unlock;
    }

    while (total < length) {
        size_t l;
        int r;

        if (!p->read_length) {
            r = pa_stream_peek(p->stream, &p->read_data, &p->read_length);
            CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
                               "pa_stream_peek failed\n");
            if (!p->read_length) {
                /* buffer is empty */
                break;
            }
        }

        l = MIN(p->read_length, length - total);
        memcpy((char *)data + total, p->read_data, l);

        p->read_data += l;
        p->read_length -= l;
        total += l;

        if (!p->read_length) {
            r = pa_stream_drop(p->stream);
            CHECK_SUCCESS_GOTO(c, r == 0, unlock_and_fail,
                               "pa_stream_drop failed\n");
        }
    }

unlock:
    pa_threaded_mainloop_unlock(c->mainloop);
    return total;

unlock_and_fail:
    pa_threaded_mainloop_unlock(c->mainloop);
    return 0;
}

static void *qpa_get_buffer_out(HWVoiceOut *hw, size_t *size)
{
    PAVoiceOut *p = (PAVoiceOut *) hw;
    PAConnection *c = p->g->conn;
    void *ret;
    size_t l;
    int r;

    pa_threaded_mainloop_lock(c->mainloop);

    CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
                    "pa_threaded_mainloop_lock failed\n");
    if (pa_stream_get_state(p->stream) != PA_STREAM_READY) {
        /* wait for stream to become ready */
        l = 0;
        ret = NULL;
        goto unlock;
    }

    l = pa_stream_writable_size(p->stream);
    CHECK_SUCCESS_GOTO(c, l != (size_t) -1, unlock_and_fail,
                       "pa_stream_writable_size failed\n");

    *size = -1;
    r = pa_stream_begin_write(p->stream, &ret, size);
    CHECK_SUCCESS_GOTO(c, r >= 0, unlock_and_fail,
                       "pa_stream_begin_write failed\n");

unlock:
    pa_threaded_mainloop_unlock(c->mainloop);
    if (*size > l) {
        *size = l;
    }
    return ret;

unlock_and_fail:
    pa_threaded_mainloop_unlock(c->mainloop);
    *size = 0;
    return NULL;
}

static size_t qpa_put_buffer_out(HWVoiceOut *hw, void *data, size_t length)
{
    PAVoiceOut *p = (PAVoiceOut *)hw;
    PAConnection *c = p->g->conn;
    int r;

    pa_threaded_mainloop_lock(c->mainloop);

    CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
                    "pa_threaded_mainloop_lock failed\n");

    r = pa_stream_write(p->stream, data, length, NULL, 0LL, PA_SEEK_RELATIVE);
    CHECK_SUCCESS_GOTO(c, r >= 0, unlock_and_fail, "pa_stream_write failed\n");

    pa_threaded_mainloop_unlock(c->mainloop);
    return length;

unlock_and_fail:
    pa_threaded_mainloop_unlock(c->mainloop);
    return 0;
}

static size_t qpa_write(HWVoiceOut *hw, void *data, size_t length)
{
    PAVoiceOut *p = (PAVoiceOut *) hw;
    PAConnection *c = p->g->conn;
    size_t l;
    int r;

    pa_threaded_mainloop_lock(c->mainloop);

    CHECK_DEAD_GOTO(c, p->stream, unlock_and_fail,
                    "pa_threaded_mainloop_lock failed\n");
    if (pa_stream_get_state(p->stream) != PA_STREAM_READY) {
        /* wait for stream to become ready */
        l = 0;
        goto unlock;
    }

    l = pa_stream_writable_size(p->stream);

    CHECK_SUCCESS_GOTO(c, l != (size_t) -1, unlock_and_fail,
                       "pa_stream_writable_size failed\n");

    if (l > length) {
        l = length;
    }

    r = pa_stream_write(p->stream, data, l, NULL, 0LL, PA_SEEK_RELATIVE);
    CHECK_SUCCESS_GOTO(c, r >= 0, unlock_and_fail, "pa_stream_write failed\n");

unlock:
    pa_threaded_mainloop_unlock(c->mainloop);
    return l;

unlock_and_fail:
    pa_threaded_mainloop_unlock(c->mainloop);
    return 0;
}

static pa_sample_format_t audfmt_to_pa (AudioFormat afmt, int endianness)
{
    int format;

    switch (afmt) {
    case AUDIO_FORMAT_S8:
    case AUDIO_FORMAT_U8:
        format = PA_SAMPLE_U8;
        break;
    case AUDIO_FORMAT_S16:
    case AUDIO_FORMAT_U16:
        format = endianness ? PA_SAMPLE_S16BE : PA_SAMPLE_S16LE;
        break;
    case AUDIO_FORMAT_S32:
    case AUDIO_FORMAT_U32:
        format = endianness ? PA_SAMPLE_S32BE : PA_SAMPLE_S32LE;
        break;
    case AUDIO_FORMAT_F32:
        format = endianness ? PA_SAMPLE_FLOAT32BE : PA_SAMPLE_FLOAT32LE;
        break;
    default:
        dolog ("Internal logic error: Bad audio format %d\n", afmt);
        format = PA_SAMPLE_U8;
        break;
    }
    return format;
}

static AudioFormat pa_to_audfmt (pa_sample_format_t fmt, int *endianness)
{
    switch (fmt) {
    case PA_SAMPLE_U8:
        return AUDIO_FORMAT_U8;
    case PA_SAMPLE_S16BE:
        *endianness = 1;
        return AUDIO_FORMAT_S16;
    case PA_SAMPLE_S16LE:
        *endianness = 0;
        return AUDIO_FORMAT_S16;
    case PA_SAMPLE_S32BE:
        *endianness = 1;
        return AUDIO_FORMAT_S32;
    case PA_SAMPLE_S32LE:
        *endianness = 0;
        return AUDIO_FORMAT_S32;
    case PA_SAMPLE_FLOAT32BE:
        *endianness = 1;
        return AUDIO_FORMAT_F32;
    case PA_SAMPLE_FLOAT32LE:
        *endianness = 0;
        return AUDIO_FORMAT_F32;
    default:
        dolog ("Internal logic error: Bad pa_sample_format %d\n", fmt);
        return AUDIO_FORMAT_U8;
    }
}

static void context_state_cb (pa_context *c, void *userdata)
{
    PAConnection *conn = userdata;

    switch (pa_context_get_state(c)) {
    case PA_CONTEXT_READY:
    case PA_CONTEXT_TERMINATED:
    case PA_CONTEXT_FAILED:
        pa_threaded_mainloop_signal(conn->mainloop, 0);
        break;

    case PA_CONTEXT_UNCONNECTED:
    case PA_CONTEXT_CONNECTING:
    case PA_CONTEXT_AUTHORIZING:
    case PA_CONTEXT_SETTING_NAME:
        break;
    }
}

static void stream_state_cb (pa_stream *s, void * userdata)
{
    PAConnection *c = userdata;

    switch (pa_stream_get_state (s)) {

    case PA_STREAM_READY:
    case PA_STREAM_FAILED:
    case PA_STREAM_TERMINATED:
        pa_threaded_mainloop_signal(c->mainloop, 0);
        break;

    case PA_STREAM_UNCONNECTED:
    case PA_STREAM_CREATING:
        break;
    }
}

static pa_stream *qpa_simple_new (
        PAConnection *c,
        const char *name,
        pa_stream_direction_t dir,
        const char *dev,
        const pa_sample_spec *ss,
        const pa_buffer_attr *attr,
        int *rerror)
{
    int r;
    pa_stream *stream = NULL;
    pa_stream_flags_t flags;
    pa_channel_map map;

    pa_threaded_mainloop_lock(c->mainloop);

    pa_channel_map_init(&map);
    map.channels = ss->channels;

    /*
     * TODO: This currently expects the only frontend supporting more than 2
     * channels is the usb-audio.  We will need some means to set channel
     * order when a new frontend gains multi-channel support.
     */
    switch (ss->channels) {
    case 1:
        map.map[0] = PA_CHANNEL_POSITION_MONO;
        break;

    case 2:
        map.map[0] = PA_CHANNEL_POSITION_LEFT;
        map.map[1] = PA_CHANNEL_POSITION_RIGHT;
        break;

    case 6:
        map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
        map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
        map.map[2] = PA_CHANNEL_POSITION_CENTER;
        map.map[3] = PA_CHANNEL_POSITION_LFE;
        map.map[4] = PA_CHANNEL_POSITION_REAR_LEFT;
        map.map[5] = PA_CHANNEL_POSITION_REAR_RIGHT;
        break;

    case 8:
        map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
        map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
        map.map[2] = PA_CHANNEL_POSITION_CENTER;
        map.map[3] = PA_CHANNEL_POSITION_LFE;
        map.map[4] = PA_CHANNEL_POSITION_REAR_LEFT;
        map.map[5] = PA_CHANNEL_POSITION_REAR_RIGHT;
        map.map[6] = PA_CHANNEL_POSITION_SIDE_LEFT;
        map.map[7] = PA_CHANNEL_POSITION_SIDE_RIGHT;
        break;

    default:
        dolog("Internal error: unsupported channel count %d\n", ss->channels);
        goto fail;
    }

    stream = pa_stream_new(c->context, name, ss, &map);
    if (!stream) {
        goto fail;
    }

    pa_stream_set_state_callback(stream, stream_state_cb, c);

    flags = PA_STREAM_EARLY_REQUESTS;

    if (dev) {
        /* don't move the stream if the user specified a sink/source */
        flags |= PA_STREAM_DONT_MOVE;
    }

    if (dir == PA_STREAM_PLAYBACK) {
        r = pa_stream_connect_playback(stream, dev, attr, flags, NULL, NULL);
    } else {
        r = pa_stream_connect_record(stream, dev, attr, flags);
    }

    if (r < 0) {
        goto fail;
    }

    pa_threaded_mainloop_unlock(c->mainloop);

    return stream;

fail:
    pa_threaded_mainloop_unlock(c->mainloop);

    if (stream) {
        pa_stream_unref (stream);
    }

    *rerror = pa_context_errno(c->context);

    return NULL;
}

static int qpa_init_out(HWVoiceOut *hw, struct audsettings *as,
                        void *drv_opaque)
{
    int error;
    pa_sample_spec ss;
    pa_buffer_attr ba;
    struct audsettings obt_as = *as;
    PAVoiceOut *pa = (PAVoiceOut *) hw;
    paaudio *g = pa->g = drv_opaque;
    AudiodevPaOptions *popts = &g->dev->u.pa;
    AudiodevPaPerDirectionOptions *ppdo = popts->out;
    PAConnection *c = g->conn;

    ss.format = audfmt_to_pa (as->fmt, as->endianness);
    ss.channels = as->nchannels;
    ss.rate = as->freq;

    ba.tlength = pa_usec_to_bytes(ppdo->latency, &ss);
    ba.minreq = pa_usec_to_bytes(MIN(ppdo->latency >> 2,
                                     (g->dev->timer_period >> 2) * 3), &ss);
    ba.maxlength = -1;
    ba.prebuf = -1;

    obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);

    pa->stream = qpa_simple_new (
        c,
        ppdo->has_stream_name ? ppdo->stream_name : g->dev->id,
        PA_STREAM_PLAYBACK,
        ppdo->has_name ? ppdo->name : NULL,
        &ss,
        &ba,                    /* buffering attributes */
        &error
        );
    if (!pa->stream) {
        qpa_logerr (error, "pa_simple_new for playback failed\n");
        goto fail1;
    }

    audio_pcm_init_info (&hw->info, &obt_as);
    /*
     * This is wrong. hw->samples counts in frames. hw->samples will be
     * number of channels times larger than expected.
     */
    hw->samples = audio_buffer_samples(
        qapi_AudiodevPaPerDirectionOptions_base(ppdo), &obt_as, 46440);

    return 0;

 fail1:
    return -1;
}

static int qpa_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
{
    int error;
    pa_sample_spec ss;
    pa_buffer_attr ba;
    struct audsettings obt_as = *as;
    PAVoiceIn *pa = (PAVoiceIn *) hw;
    paaudio *g = pa->g = drv_opaque;
    AudiodevPaOptions *popts = &g->dev->u.pa;
    AudiodevPaPerDirectionOptions *ppdo = popts->in;
    PAConnection *c = g->conn;

    ss.format = audfmt_to_pa (as->fmt, as->endianness);
    ss.channels = as->nchannels;
    ss.rate = as->freq;

    ba.fragsize = pa_usec_to_bytes((g->dev->timer_period >> 1) * 3, &ss);
    ba.maxlength = pa_usec_to_bytes(
        MAX(ppdo->latency, g->dev->timer_period * 3), &ss);
    ba.minreq = -1;
    ba.prebuf = -1;

    obt_as.fmt = pa_to_audfmt (ss.format, &obt_as.endianness);

    pa->stream = qpa_simple_new (
        c,
        ppdo->has_stream_name ? ppdo->stream_name : g->dev->id,
        PA_STREAM_RECORD,
        ppdo->has_name ? ppdo->name : NULL,
        &ss,
        &ba,                    /* buffering attributes */
        &error
        );
    if (!pa->stream) {
        qpa_logerr (error, "pa_simple_new for capture failed\n");
        goto fail1;
    }

    audio_pcm_init_info (&hw->info, &obt_as);
    /*
     * This is wrong. hw->samples counts in frames. hw->samples will be
     * number of channels times larger than expected.
     */
    hw->samples = audio_buffer_samples(
        qapi_AudiodevPaPerDirectionOptions_base(ppdo), &obt_as, 46440);

    return 0;

 fail1:
    return -1;
}

static void qpa_simple_disconnect(PAConnection *c, pa_stream *stream)
{
    int err;

    /*
     * wait until actually connects. workaround pa bug #247
     * https://gitlab.freedesktop.org/pulseaudio/pulseaudio/issues/247
     */
    while (pa_stream_get_state(stream) == PA_STREAM_CREATING) {
        pa_threaded_mainloop_wait(c->mainloop);
    }

    err = pa_stream_disconnect(stream);
    if (err != 0) {
        dolog("Failed to disconnect! err=%d\n", err);
    }
    pa_stream_unref(stream);
}

static void qpa_fini_out (HWVoiceOut *hw)
{
    PAVoiceOut *pa = (PAVoiceOut *) hw;

    if (pa->stream) {
        PAConnection *c = pa->g->conn;

        pa_threaded_mainloop_lock(c->mainloop);
        qpa_simple_disconnect(c, pa->stream);
        pa->stream = NULL;
        pa_threaded_mainloop_unlock(c->mainloop);
    }
}

static void qpa_fini_in (HWVoiceIn *hw)
{
    PAVoiceIn *pa = (PAVoiceIn *) hw;

    if (pa->stream) {
        PAConnection *c = pa->g->conn;

        pa_threaded_mainloop_lock(c->mainloop);
        if (pa->read_length) {
            int r = pa_stream_drop(pa->stream);
            if (r) {
                qpa_logerr(pa_context_errno(c->context),
                           "pa_stream_drop failed\n");
            }
            pa->read_length = 0;
        }
        qpa_simple_disconnect(c, pa->stream);
        pa->stream = NULL;
        pa_threaded_mainloop_unlock(c->mainloop);
    }
}

static void qpa_volume_out(HWVoiceOut *hw, Volume *vol)
{
    PAVoiceOut *pa = (PAVoiceOut *) hw;
    pa_operation *op;
    pa_cvolume v;
    PAConnection *c = pa->g->conn;
    int i;

#ifdef PA_CHECK_VERSION    /* macro is present in 0.9.16+ */
    pa_cvolume_init (&v);  /* function is present in 0.9.13+ */
#endif

    v.channels = vol->channels;
    for (i = 0; i < vol->channels; ++i) {
        v.values[i] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->vol[i]) / 255;
    }

    pa_threaded_mainloop_lock(c->mainloop);

    op = pa_context_set_sink_input_volume(c->context,
                                          pa_stream_get_index(pa->stream),
                                          &v, NULL, NULL);
    if (!op) {
        qpa_logerr(pa_context_errno(c->context),
                   "set_sink_input_volume() failed\n");
    } else {
        pa_operation_unref(op);
    }

    op = pa_context_set_sink_input_mute(c->context,
                                        pa_stream_get_index(pa->stream),
                                        vol->mute, NULL, NULL);
    if (!op) {
        qpa_logerr(pa_context_errno(c->context),
                   "set_sink_input_mute() failed\n");
    } else {
        pa_operation_unref(op);
    }

    pa_threaded_mainloop_unlock(c->mainloop);
}

static void qpa_volume_in(HWVoiceIn *hw, Volume *vol)
{
    PAVoiceIn *pa = (PAVoiceIn *) hw;
    pa_operation *op;
    pa_cvolume v;
    PAConnection *c = pa->g->conn;
    int i;

#ifdef PA_CHECK_VERSION
    pa_cvolume_init (&v);
#endif

    v.channels = vol->channels;
    for (i = 0; i < vol->channels; ++i) {
        v.values[i] = ((PA_VOLUME_NORM - PA_VOLUME_MUTED) * vol->vol[i]) / 255;
    }

    pa_threaded_mainloop_lock(c->mainloop);

    op = pa_context_set_source_output_volume(c->context,
        pa_stream_get_index(pa->stream),
        &v, NULL, NULL);
    if (!op) {
        qpa_logerr(pa_context_errno(c->context),
                   "set_source_output_volume() failed\n");
    } else {
        pa_operation_unref(op);
    }

    op = pa_context_set_source_output_mute(c->context,
        pa_stream_get_index(pa->stream),
        vol->mute, NULL, NULL);
    if (!op) {
        qpa_logerr(pa_context_errno(c->context),
                   "set_source_output_mute() failed\n");
    } else {
        pa_operation_unref(op);
    }

    pa_threaded_mainloop_unlock(c->mainloop);
}

static int qpa_validate_per_direction_opts(Audiodev *dev,
                                           AudiodevPaPerDirectionOptions *pdo)
{
    if (!pdo->has_latency) {
        pdo->has_latency = true;
        pdo->latency = 15000;
    }
    return 1;
}

/* common */
static void *qpa_conn_init(const char *server)
{
    PAConnection *c = g_malloc0(sizeof(PAConnection));
    QTAILQ_INSERT_TAIL(&pa_conns, c, list);

    c->mainloop = pa_threaded_mainloop_new();
    if (!c->mainloop) {
        goto fail;
    }

    c->context = pa_context_new(pa_threaded_mainloop_get_api(c->mainloop),
                                audio_application_name());
    if (!c->context) {
        goto fail;
    }

    pa_context_set_state_callback(c->context, context_state_cb, c);

    if (pa_context_connect(c->context, server, 0, NULL) < 0) {
        qpa_logerr(pa_context_errno(c->context),
                   "pa_context_connect() failed\n");
        goto fail;
    }

    pa_threaded_mainloop_lock(c->mainloop);

    if (pa_threaded_mainloop_start(c->mainloop) < 0) {
        goto unlock_and_fail;
    }

    for (;;) {
        pa_context_state_t state;

        state = pa_context_get_state(c->context);

        if (state == PA_CONTEXT_READY) {
            break;
        }

        if (!PA_CONTEXT_IS_GOOD(state)) {
            qpa_logerr(pa_context_errno(c->context),
                       "Wrong context state\n");
            goto unlock_and_fail;
        }

        /* Wait until the context is ready */
        pa_threaded_mainloop_wait(c->mainloop);
    }

    pa_threaded_mainloop_unlock(c->mainloop);
    return c;

unlock_and_fail:
    pa_threaded_mainloop_unlock(c->mainloop);
fail:
    AUD_log (AUDIO_CAP, "Failed to initialize PA context");
    qpa_conn_fini(c);
    return NULL;
}

static void *qpa_audio_init(Audiodev *dev)
{
    paaudio *g;
    AudiodevPaOptions *popts = &dev->u.pa;
    const char *server;
    PAConnection *c;

    assert(dev->driver == AUDIODEV_DRIVER_PA);

    if (!popts->has_server) {
        char pidfile[64];
        char *runtime;
        struct stat st;

        runtime = getenv("XDG_RUNTIME_DIR");
        if (!runtime) {
            return NULL;
        }
        snprintf(pidfile, sizeof(pidfile), "%s/pulse/pid", runtime);
        if (stat(pidfile, &st) != 0) {
            return NULL;
        }
    }

    if (!qpa_validate_per_direction_opts(dev, popts->in)) {
        return NULL;
    }
    if (!qpa_validate_per_direction_opts(dev, popts->out)) {
        return NULL;
    }

    g = g_malloc0(sizeof(paaudio));
    server = popts->has_server ? popts->server : NULL;

    g->dev = dev;

    QTAILQ_FOREACH(c, &pa_conns, list) {
        if (server == NULL || c->server == NULL ?
            server == c->server :
            strcmp(server, c->server) == 0) {
            g->conn = c;
            break;
        }
    }
    if (!g->conn) {
        g->conn = qpa_conn_init(server);
    }
    if (!g->conn) {
        g_free(g);
        return NULL;
    }

    ++g->conn->refcount;
    return g;
}

static void qpa_conn_fini(PAConnection *c)
{
    if (c->mainloop) {
        pa_threaded_mainloop_stop(c->mainloop);
    }

    if (c->context) {
        pa_context_disconnect(c->context);
        pa_context_unref(c->context);
    }

    if (c->mainloop) {
        pa_threaded_mainloop_free(c->mainloop);
    }

    QTAILQ_REMOVE(&pa_conns, c, list);
    g_free(c);
}

static void qpa_audio_fini (void *opaque)
{
    paaudio *g = opaque;
    PAConnection *c = g->conn;

    if (--c->refcount == 0) {
        qpa_conn_fini(c);
    }

    g_free(g);
}

static struct audio_pcm_ops qpa_pcm_ops = {
    .init_out = qpa_init_out,
    .fini_out = qpa_fini_out,
    .write    = qpa_write,
    .get_buffer_out = qpa_get_buffer_out,
    .put_buffer_out = qpa_put_buffer_out,
    .volume_out = qpa_volume_out,

    .init_in  = qpa_init_in,
    .fini_in  = qpa_fini_in,
    .read     = qpa_read,
    .get_buffer_in = qpa_get_buffer_in,
    .put_buffer_in = qpa_put_buffer_in,
    .volume_in = qpa_volume_in
};

static struct audio_driver pa_audio_driver = {
    .name           = "pa",
    .descr          = "http://www.pulseaudio.org/",
    .init           = qpa_audio_init,
    .fini           = qpa_audio_fini,
    .pcm_ops        = &qpa_pcm_ops,
    .can_be_default = 1,
    .max_voices_out = INT_MAX,
    .max_voices_in  = INT_MAX,
    .voice_size_out = sizeof (PAVoiceOut),
    .voice_size_in  = sizeof (PAVoiceIn),
};

static void register_audio_pa(void)
{
    audio_driver_register(&pa_audio_driver);
}
type_init(register_audio_pa);
