/*
 * QEMU OSS audio driver
 *
 * Copyright (c) 2003-2005 Vassili Karpov (malc)
 *
 * 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 <sys/ioctl.h>
#include <sys/soundcard.h>
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/host-utils.h"
#include "qapi/error.h"
#include "audio.h"
#include "trace.h"

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

#if defined OSS_GETVERSION && defined SNDCTL_DSP_POLICY
#define USE_DSP_POLICY
#endif

typedef struct OSSVoiceOut {
    HWVoiceOut hw;
    int fd;
    int nfrags;
    int fragsize;
    int mmapped;
    Audiodev *dev;
} OSSVoiceOut;

typedef struct OSSVoiceIn {
    HWVoiceIn hw;
    int fd;
    int nfrags;
    int fragsize;
    Audiodev *dev;
} OSSVoiceIn;

struct oss_params {
    int freq;
    int fmt;
    int nchannels;
    int nfrags;
    int fragsize;
};

static void G_GNUC_PRINTF (2, 3) oss_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", strerror (err));
}

static void G_GNUC_PRINTF (3, 4) oss_logerr2 (
    int err,
    const char *typ,
    const char *fmt,
    ...
    )
{
    va_list ap;

    AUD_log (AUDIO_CAP, "Could not initialize %s\n", typ);

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

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

static void oss_anal_close (int *fdp)
{
    int err;

    qemu_set_fd_handler (*fdp, NULL, NULL, NULL);
    err = close (*fdp);
    if (err) {
        oss_logerr (errno, "Failed to close file(fd=%d)\n", *fdp);
    }
    *fdp = -1;
}

static void oss_helper_poll_out (void *opaque)
{
    AudioState *s = opaque;
    audio_run(s, "oss_poll_out");
}

static void oss_helper_poll_in (void *opaque)
{
    AudioState *s = opaque;
    audio_run(s, "oss_poll_in");
}

static void oss_poll_out (HWVoiceOut *hw)
{
    OSSVoiceOut *oss = (OSSVoiceOut *) hw;

    qemu_set_fd_handler(oss->fd, NULL, oss_helper_poll_out, hw->s);
}

static void oss_poll_in (HWVoiceIn *hw)
{
    OSSVoiceIn *oss = (OSSVoiceIn *) hw;

    qemu_set_fd_handler(oss->fd, oss_helper_poll_in, NULL, hw->s);
}

static int aud_to_ossfmt (AudioFormat fmt, int endianness)
{
    switch (fmt) {
    case AUDIO_FORMAT_S8:
        return AFMT_S8;

    case AUDIO_FORMAT_U8:
        return AFMT_U8;

    case AUDIO_FORMAT_S16:
        if (endianness) {
            return AFMT_S16_BE;
        } else {
            return AFMT_S16_LE;
        }

    case AUDIO_FORMAT_U16:
        if (endianness) {
            return AFMT_U16_BE;
        } else {
            return AFMT_U16_LE;
        }

    default:
        dolog ("Internal logic error: Bad audio format %d\n", fmt);
#ifdef DEBUG_AUDIO
        abort ();
#endif
        return AFMT_U8;
    }
}

static int oss_to_audfmt (int ossfmt, AudioFormat *fmt, int *endianness)
{
    switch (ossfmt) {
    case AFMT_S8:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_S8;
        break;

    case AFMT_U8:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_U8;
        break;

    case AFMT_S16_LE:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_S16;
        break;

    case AFMT_U16_LE:
        *endianness = 0;
        *fmt = AUDIO_FORMAT_U16;
        break;

    case AFMT_S16_BE:
        *endianness = 1;
        *fmt = AUDIO_FORMAT_S16;
        break;

    case AFMT_U16_BE:
        *endianness = 1;
        *fmt = AUDIO_FORMAT_U16;
        break;

    default:
        dolog ("Unrecognized audio format %d\n", ossfmt);
        return -1;
    }

    return 0;
}

#if defined DEBUG_MISMATCHES || defined DEBUG
static void oss_dump_info (struct oss_params *req, struct oss_params *obt)
{
    dolog ("parameter | requested value | obtained value\n");
    dolog ("format    |      %10d |     %10d\n", req->fmt, obt->fmt);
    dolog ("channels  |      %10d |     %10d\n",
           req->nchannels, obt->nchannels);
    dolog ("frequency |      %10d |     %10d\n", req->freq, obt->freq);
    dolog ("nfrags    |      %10d |     %10d\n", req->nfrags, obt->nfrags);
    dolog ("fragsize  |      %10d |     %10d\n",
           req->fragsize, obt->fragsize);
}
#endif

#ifdef USE_DSP_POLICY
static int oss_get_version (int fd, int *version, const char *typ)
{
    if (ioctl (fd, OSS_GETVERSION, &version)) {
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
        /*
         * Looks like atm (20100109) FreeBSD knows OSS_GETVERSION
         * since 7.x, but currently only on the mixer device (or in
         * the Linuxolator), and in the native version that part of
         * the code is in fact never reached so the ioctl fails anyway.
         * Until this is fixed, just check the errno and if its what
         * FreeBSD's sound drivers return atm assume they are new enough.
         */
        if (errno == EINVAL) {
            *version = 0x040000;
            return 0;
        }
#endif
        oss_logerr2 (errno, typ, "Failed to get OSS version\n");
        return -1;
    }
    return 0;
}
#endif

static int oss_open(int in, struct oss_params *req, audsettings *as,
                    struct oss_params *obt, int *pfd, Audiodev *dev)
{
    AudiodevOssOptions *oopts = &dev->u.oss;
    AudiodevOssPerDirectionOptions *opdo = in ? oopts->in : oopts->out;
    int fd;
    int oflags = (oopts->has_exclusive && oopts->exclusive) ? O_EXCL : 0;
    audio_buf_info abinfo;
    int fmt, freq, nchannels;
    int setfragment = 1;
    const char *dspname = opdo->dev ?: "/dev/dsp";
    const char *typ = in ? "ADC" : "DAC";
#ifdef USE_DSP_POLICY
    int policy = oopts->has_dsp_policy ? oopts->dsp_policy : 5;
#endif

    /* Kludge needed to have working mmap on Linux */
    oflags |= (oopts->has_try_mmap && oopts->try_mmap) ?
        O_RDWR : (in ? O_RDONLY : O_WRONLY);

    fd = open (dspname, oflags | O_NONBLOCK);
    if (-1 == fd) {
        oss_logerr2 (errno, typ, "Failed to open `%s'\n", dspname);
        return -1;
    }

    freq = req->freq;
    nchannels = req->nchannels;
    fmt = req->fmt;
    req->nfrags = opdo->has_buffer_count ? opdo->buffer_count : 4;
    req->fragsize = audio_buffer_bytes(
        qapi_AudiodevOssPerDirectionOptions_base(opdo), as, 23220);

    if (ioctl (fd, SNDCTL_DSP_SAMPLESIZE, &fmt)) {
        oss_logerr2 (errno, typ, "Failed to set sample size %d\n", req->fmt);
        goto err;
    }

    if (ioctl (fd, SNDCTL_DSP_CHANNELS, &nchannels)) {
        oss_logerr2 (errno, typ, "Failed to set number of channels %d\n",
                     req->nchannels);
        goto err;
    }

    if (ioctl (fd, SNDCTL_DSP_SPEED, &freq)) {
        oss_logerr2 (errno, typ, "Failed to set frequency %d\n", req->freq);
        goto err;
    }

    if (ioctl (fd, SNDCTL_DSP_NONBLOCK, NULL)) {
        oss_logerr2 (errno, typ, "Failed to set non-blocking mode\n");
        goto err;
    }

#ifdef USE_DSP_POLICY
    if (policy >= 0) {
        int version;

        if (!oss_get_version (fd, &version, typ)) {
            trace_oss_version(version);

            if (version >= 0x040000) {
                int policy2 = policy;
                if (ioctl(fd, SNDCTL_DSP_POLICY, &policy2)) {
                    oss_logerr2 (errno, typ,
                                 "Failed to set timing policy to %d\n",
                                 policy);
                    goto err;
                }
                setfragment = 0;
            }
        }
    }
#endif

    if (setfragment) {
        int mmmmssss = (req->nfrags << 16) | ctz32 (req->fragsize);
        if (ioctl (fd, SNDCTL_DSP_SETFRAGMENT, &mmmmssss)) {
            oss_logerr2 (errno, typ, "Failed to set buffer length (%d, %d)\n",
                         req->nfrags, req->fragsize);
            goto err;
        }
    }

    if (ioctl (fd, in ? SNDCTL_DSP_GETISPACE : SNDCTL_DSP_GETOSPACE, &abinfo)) {
        oss_logerr2 (errno, typ, "Failed to get buffer length\n");
        goto err;
    }

    if (!abinfo.fragstotal || !abinfo.fragsize) {
        AUD_log (AUDIO_CAP, "Returned bogus buffer information(%d, %d) for %s\n",
                 abinfo.fragstotal, abinfo.fragsize, typ);
        goto err;
    }

    obt->fmt = fmt;
    obt->nchannels = nchannels;
    obt->freq = freq;
    obt->nfrags = abinfo.fragstotal;
    obt->fragsize = abinfo.fragsize;
    *pfd = fd;

#ifdef DEBUG_MISMATCHES
    if ((req->fmt != obt->fmt) ||
        (req->nchannels != obt->nchannels) ||
        (req->freq != obt->freq) ||
        (req->fragsize != obt->fragsize) ||
        (req->nfrags != obt->nfrags)) {
        dolog ("Audio parameters mismatch\n");
        oss_dump_info (req, obt);
    }
#endif

#ifdef DEBUG
    oss_dump_info (req, obt);
#endif
    return 0;

 err:
    oss_anal_close (&fd);
    return -1;
}

static size_t oss_get_available_bytes(OSSVoiceOut *oss)
{
    int err;
    struct count_info cntinfo;
    assert(oss->mmapped);

    err = ioctl(oss->fd, SNDCTL_DSP_GETOPTR, &cntinfo);
    if (err < 0) {
        oss_logerr(errno, "SNDCTL_DSP_GETOPTR failed\n");
        return 0;
    }

    return audio_ring_dist(cntinfo.ptr, oss->hw.pos_emul, oss->hw.size_emul);
}

static void oss_run_buffer_out(HWVoiceOut *hw)
{
    OSSVoiceOut *oss = (OSSVoiceOut *)hw;

    if (!oss->mmapped) {
        audio_generic_run_buffer_out(hw);
    }
}

static size_t oss_buffer_get_free(HWVoiceOut *hw)
{
    OSSVoiceOut *oss = (OSSVoiceOut *)hw;

    if (oss->mmapped) {
        return oss_get_available_bytes(oss);
    } else {
        return audio_generic_buffer_get_free(hw);
    }
}

static void *oss_get_buffer_out(HWVoiceOut *hw, size_t *size)
{
    OSSVoiceOut *oss = (OSSVoiceOut *)hw;

    if (oss->mmapped) {
        *size = hw->size_emul - hw->pos_emul;
        return hw->buf_emul + hw->pos_emul;
    } else {
        return audio_generic_get_buffer_out(hw, size);
    }
}

static size_t oss_put_buffer_out(HWVoiceOut *hw, void *buf, size_t size)
{
    OSSVoiceOut *oss = (OSSVoiceOut *) hw;
    if (oss->mmapped) {
        assert(buf == hw->buf_emul + hw->pos_emul && size < hw->size_emul);

        hw->pos_emul = (hw->pos_emul + size) % hw->size_emul;
        return size;
    } else {
        return audio_generic_put_buffer_out(hw, buf, size);
    }
}

static size_t oss_write(HWVoiceOut *hw, void *buf, size_t len)
{
    OSSVoiceOut *oss = (OSSVoiceOut *) hw;
    size_t pos;

    if (oss->mmapped) {
        size_t total_len;
        len = MIN(len, oss_get_available_bytes(oss));

        total_len = len;
        while (len) {
            size_t to_copy = MIN(len, hw->size_emul - hw->pos_emul);
            memcpy(hw->buf_emul + hw->pos_emul, buf, to_copy);

            hw->pos_emul = (hw->pos_emul + to_copy) % hw->size_emul;
            buf += to_copy;
            len -= to_copy;
        }
        return total_len;
    }

    pos = 0;
    while (len) {
        ssize_t bytes_written;
        void *pcm = advance(buf, pos);

        bytes_written = write(oss->fd, pcm, len);
        if (bytes_written < 0) {
            if (errno != EAGAIN) {
                oss_logerr(errno, "failed to write %zu bytes\n",
                           len);
            }
            return pos;
        }

        pos += bytes_written;
        if (bytes_written < len) {
            break;
        }
        len -= bytes_written;
    }
    return pos;
}

static void oss_fini_out (HWVoiceOut *hw)
{
    int err;
    OSSVoiceOut *oss = (OSSVoiceOut *) hw;

    ldebug ("oss_fini\n");
    oss_anal_close (&oss->fd);

    if (oss->mmapped && hw->buf_emul) {
        err = munmap(hw->buf_emul, hw->size_emul);
        if (err) {
            oss_logerr(errno, "Failed to unmap buffer %p, size %zu\n",
                       hw->buf_emul, hw->size_emul);
        }
        hw->buf_emul = NULL;
    }
}

static int oss_init_out(HWVoiceOut *hw, struct audsettings *as,
                        void *drv_opaque)
{
    OSSVoiceOut *oss = (OSSVoiceOut *) hw;
    struct oss_params req, obt;
    int endianness;
    int err;
    int fd;
    AudioFormat effective_fmt;
    struct audsettings obt_as;
    Audiodev *dev = drv_opaque;
    AudiodevOssOptions *oopts = &dev->u.oss;

    oss->fd = -1;

    req.fmt = aud_to_ossfmt (as->fmt, as->endianness);
    req.freq = as->freq;
    req.nchannels = as->nchannels;

    if (oss_open(0, &req, as, &obt, &fd, dev)) {
        return -1;
    }

    err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);
    if (err) {
        oss_anal_close (&fd);
        return -1;
    }

    obt_as.freq = obt.freq;
    obt_as.nchannels = obt.nchannels;
    obt_as.fmt = effective_fmt;
    obt_as.endianness = endianness;

    audio_pcm_init_info (&hw->info, &obt_as);
    oss->nfrags = obt.nfrags;
    oss->fragsize = obt.fragsize;

    if (obt.nfrags * obt.fragsize % hw->info.bytes_per_frame) {
        dolog ("warning: Misaligned DAC buffer, size %d, alignment %d\n",
               obt.nfrags * obt.fragsize, hw->info.bytes_per_frame);
    }

    hw->samples = (obt.nfrags * obt.fragsize) / hw->info.bytes_per_frame;

    oss->mmapped = 0;
    if (oopts->has_try_mmap && oopts->try_mmap) {
        hw->size_emul = hw->samples * hw->info.bytes_per_frame;
        hw->buf_emul = mmap(
            NULL,
            hw->size_emul,
            PROT_READ | PROT_WRITE,
            MAP_SHARED,
            fd,
            0
            );
        if (hw->buf_emul == MAP_FAILED) {
            oss_logerr(errno, "Failed to map %zu bytes of DAC\n",
                       hw->size_emul);
            hw->buf_emul = NULL;
        } else {
            int trig = 0;
            if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
                oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");
            } else {
                trig = PCM_ENABLE_OUTPUT;
                if (ioctl (fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
                    oss_logerr (
                        errno,
                        "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n"
                        );
                } else {
                    oss->mmapped = 1;
                }
            }

            if (!oss->mmapped) {
                err = munmap(hw->buf_emul, hw->size_emul);
                if (err) {
                    oss_logerr(errno, "Failed to unmap buffer %p size %zu\n",
                               hw->buf_emul, hw->size_emul);
                }
                hw->buf_emul = NULL;
            }
        }
    }

    oss->fd = fd;
    oss->dev = dev;
    return 0;
}

static void oss_enable_out(HWVoiceOut *hw, bool enable)
{
    int trig;
    OSSVoiceOut *oss = (OSSVoiceOut *) hw;
    AudiodevOssPerDirectionOptions *opdo = oss->dev->u.oss.out;

    if (enable) {
        hw->poll_mode = opdo->try_poll;

        ldebug("enabling voice\n");
        if (hw->poll_mode) {
            oss_poll_out(hw);
        }

        if (!oss->mmapped) {
            return;
        }

        audio_pcm_info_clear_buf(&hw->info, hw->buf_emul, hw->samples);
        trig = PCM_ENABLE_OUTPUT;
        if (ioctl(oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
            oss_logerr(errno,
                       "SNDCTL_DSP_SETTRIGGER PCM_ENABLE_OUTPUT failed\n");
            return;
        }
    } else {
        if (hw->poll_mode) {
            qemu_set_fd_handler (oss->fd, NULL, NULL, NULL);
            hw->poll_mode = 0;
        }

        if (!oss->mmapped) {
            return;
        }

        ldebug ("disabling voice\n");
        trig = 0;
        if (ioctl (oss->fd, SNDCTL_DSP_SETTRIGGER, &trig) < 0) {
            oss_logerr (errno, "SNDCTL_DSP_SETTRIGGER 0 failed\n");
            return;
        }
    }
}

static int oss_init_in(HWVoiceIn *hw, struct audsettings *as, void *drv_opaque)
{
    OSSVoiceIn *oss = (OSSVoiceIn *) hw;
    struct oss_params req, obt;
    int endianness;
    int err;
    int fd;
    AudioFormat effective_fmt;
    struct audsettings obt_as;
    Audiodev *dev = drv_opaque;

    oss->fd = -1;

    req.fmt = aud_to_ossfmt (as->fmt, as->endianness);
    req.freq = as->freq;
    req.nchannels = as->nchannels;
    if (oss_open(1, &req, as, &obt, &fd, dev)) {
        return -1;
    }

    err = oss_to_audfmt (obt.fmt, &effective_fmt, &endianness);
    if (err) {
        oss_anal_close (&fd);
        return -1;
    }

    obt_as.freq = obt.freq;
    obt_as.nchannels = obt.nchannels;
    obt_as.fmt = effective_fmt;
    obt_as.endianness = endianness;

    audio_pcm_init_info (&hw->info, &obt_as);
    oss->nfrags = obt.nfrags;
    oss->fragsize = obt.fragsize;

    if (obt.nfrags * obt.fragsize % hw->info.bytes_per_frame) {
        dolog ("warning: Misaligned ADC buffer, size %d, alignment %d\n",
               obt.nfrags * obt.fragsize, hw->info.bytes_per_frame);
    }

    hw->samples = (obt.nfrags * obt.fragsize) / hw->info.bytes_per_frame;

    oss->fd = fd;
    oss->dev = dev;
    return 0;
}

static void oss_fini_in (HWVoiceIn *hw)
{
    OSSVoiceIn *oss = (OSSVoiceIn *) hw;

    oss_anal_close (&oss->fd);
}

static size_t oss_read(HWVoiceIn *hw, void *buf, size_t len)
{
    OSSVoiceIn *oss = (OSSVoiceIn *) hw;
    size_t pos = 0;

    while (len) {
        ssize_t nread;

        void *dst = advance(buf, pos);
        nread = read(oss->fd, dst, len);

        if (nread == -1) {
            switch (errno) {
            case EINTR:
            case EAGAIN:
                break;
            default:
                oss_logerr(errno, "Failed to read %zu bytes of audio (to %p)\n",
                           len, dst);
                break;
            }
            break;
        }

        pos += nread;
        len -= nread;
    }

    return pos;
}

static void oss_enable_in(HWVoiceIn *hw, bool enable)
{
    OSSVoiceIn *oss = (OSSVoiceIn *) hw;
    AudiodevOssPerDirectionOptions *opdo = oss->dev->u.oss.out;

    if (enable) {
        hw->poll_mode = opdo->try_poll;

        if (hw->poll_mode) {
            oss_poll_in(hw);
        }
    } else {
        if (hw->poll_mode) {
            qemu_set_fd_handler (oss->fd, NULL, NULL, NULL);
            hw->poll_mode = 0;
        }
    }
}

static void oss_init_per_direction(AudiodevOssPerDirectionOptions *opdo)
{
    if (!opdo->has_try_poll) {
        opdo->try_poll = true;
        opdo->has_try_poll = true;
    }
}

static void *oss_audio_init(Audiodev *dev, Error **errp)
{
    AudiodevOssOptions *oopts;
    assert(dev->driver == AUDIODEV_DRIVER_OSS);

    oopts = &dev->u.oss;
    oss_init_per_direction(oopts->in);
    oss_init_per_direction(oopts->out);

    if (access(oopts->in->dev ?: "/dev/dsp", R_OK | W_OK) < 0) {
        error_setg_errno(errp, errno, "%s not accessible", oopts->in->dev ?: "/dev/dsp");
        return NULL;
    }
    if (access(oopts->out->dev ?: "/dev/dsp", R_OK | W_OK) < 0) {
        error_setg_errno(errp, errno, "%s not accessible", oopts->out->dev ?: "/dev/dsp");
        return NULL;
    }
    return dev;
}

static void oss_audio_fini (void *opaque)
{
}

static struct audio_pcm_ops oss_pcm_ops = {
    .init_out = oss_init_out,
    .fini_out = oss_fini_out,
    .write    = oss_write,
    .buffer_get_free = oss_buffer_get_free,
    .run_buffer_out = oss_run_buffer_out,
    .get_buffer_out = oss_get_buffer_out,
    .put_buffer_out = oss_put_buffer_out,
    .enable_out = oss_enable_out,

    .init_in  = oss_init_in,
    .fini_in  = oss_fini_in,
    .read     = oss_read,
    .run_buffer_in = audio_generic_run_buffer_in,
    .enable_in = oss_enable_in
};

static struct audio_driver oss_audio_driver = {
    .name           = "oss",
    .descr          = "OSS http://www.opensound.com",
    .init           = oss_audio_init,
    .fini           = oss_audio_fini,
    .pcm_ops        = &oss_pcm_ops,
    .max_voices_out = INT_MAX,
    .max_voices_in  = INT_MAX,
    .voice_size_out = sizeof (OSSVoiceOut),
    .voice_size_in  = sizeof (OSSVoiceIn)
};

static void register_audio_oss(void)
{
    audio_driver_register(&oss_audio_driver);
}
type_init(register_audio_oss);
