#include "hw/hw.h"
#include "monitor/monitor.h"
#include "audio.h"

typedef struct {
    FILE *f;
    int bytes;
    char *path;
    int freq;
    int bits;
    int nchannels;
    CaptureVoiceOut *cap;
} WAVState;

/* VICE code: Store number as little endian. */
static void le_store (uint8_t *buf, uint32_t val, int len)
{
    int i;
    for (i = 0; i < len; i++) {
        buf[i] = (uint8_t) (val & 0xff);
        val >>= 8;
    }
}

static void wav_notify (void *opaque, audcnotification_e cmd)
{
    (void) opaque;
    (void) cmd;
}

static void wav_destroy (void *opaque)
{
    WAVState *wav = opaque;
    uint8_t rlen[4];
    uint8_t dlen[4];
    uint32_t datalen = wav->bytes;
    uint32_t rifflen = datalen + 36;
    Monitor *mon = cur_mon;

    if (wav->f) {
        le_store (rlen, rifflen, 4);
        le_store (dlen, datalen, 4);

        if (fseek (wav->f, 4, SEEK_SET)) {
            monitor_printf (mon, "wav_destroy: rlen fseek failed\nReason: %s\n",
                            strerror (errno));
            goto doclose;
        }
        if (fwrite (rlen, 4, 1, wav->f) != 1) {
            monitor_printf (mon, "wav_destroy: rlen fwrite failed\nReason %s\n",
                            strerror (errno));
            goto doclose;
        }
        if (fseek (wav->f, 32, SEEK_CUR)) {
            monitor_printf (mon, "wav_destroy: dlen fseek failed\nReason %s\n",
                            strerror (errno));
            goto doclose;
        }
        if (fwrite (dlen, 1, 4, wav->f) != 4) {
            monitor_printf (mon, "wav_destroy: dlen fwrite failed\nReason %s\n",
                            strerror (errno));
            goto doclose;
        }
    doclose:
        if (fclose (wav->f)) {
            error_report("wav_destroy: fclose failed: %s", strerror(errno));
        }
    }

    g_free (wav->path);
}

static void wav_capture (void *opaque, void *buf, int size)
{
    WAVState *wav = opaque;

    if (fwrite (buf, size, 1, wav->f) != 1) {
        monitor_printf (cur_mon, "wav_capture: fwrite error\nReason: %s",
                        strerror (errno));
    }
    wav->bytes += size;
}

static void wav_capture_destroy (void *opaque)
{
    WAVState *wav = opaque;

    AUD_del_capture (wav->cap, wav);
}

static void wav_capture_info (void *opaque)
{
    WAVState *wav = opaque;
    char *path = wav->path;

    monitor_printf (cur_mon, "Capturing audio(%d,%d,%d) to %s: %d bytes\n",
                    wav->freq, wav->bits, wav->nchannels,
                    path ? path : "<not available>", wav->bytes);
}

static struct capture_ops wav_capture_ops = {
    .destroy = wav_capture_destroy,
    .info = wav_capture_info
};

int wav_start_capture (CaptureState *s, const char *path, int freq,
                       int bits, int nchannels)
{
    Monitor *mon = cur_mon;
    WAVState *wav;
    uint8_t hdr[] = {
        0x52, 0x49, 0x46, 0x46, 0x00, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56,
        0x45, 0x66, 0x6d, 0x74, 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00,
        0x02, 0x00, 0x44, 0xac, 0x00, 0x00, 0x10, 0xb1, 0x02, 0x00, 0x04,
        0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00
    };
    struct audsettings as;
    struct audio_capture_ops ops;
    int stereo, bits16, shift;
    CaptureVoiceOut *cap;

    if (bits != 8 && bits != 16) {
        monitor_printf (mon, "incorrect bit count %d, must be 8 or 16\n", bits);
        return -1;
    }

    if (nchannels != 1 && nchannels != 2) {
        monitor_printf (mon, "incorrect channel count %d, must be 1 or 2\n",
                        nchannels);
        return -1;
    }

    stereo = nchannels == 2;
    bits16 = bits == 16;

    as.freq = freq;
    as.nchannels = 1 << stereo;
    as.fmt = bits16 ? AUD_FMT_S16 : AUD_FMT_U8;
    as.endianness = 0;

    ops.notify = wav_notify;
    ops.capture = wav_capture;
    ops.destroy = wav_destroy;

    wav = g_malloc0 (sizeof (*wav));

    shift = bits16 + stereo;
    hdr[34] = bits16 ? 0x10 : 0x08;

    le_store (hdr + 22, as.nchannels, 2);
    le_store (hdr + 24, freq, 4);
    le_store (hdr + 28, freq << shift, 4);
    le_store (hdr + 32, 1 << shift, 2);

    wav->f = fopen (path, "wb");
    if (!wav->f) {
        monitor_printf (mon, "Failed to open wave file `%s'\nReason: %s\n",
                        path, strerror (errno));
        g_free (wav);
        return -1;
    }

    wav->path = g_strdup (path);
    wav->bits = bits;
    wav->nchannels = nchannels;
    wav->freq = freq;

    if (fwrite (hdr, sizeof (hdr), 1, wav->f) != 1) {
        monitor_printf (mon, "Failed to write header\nReason: %s\n",
                        strerror (errno));
        goto error_free;
    }

    cap = AUD_add_capture (&as, &ops, wav);
    if (!cap) {
        monitor_printf (mon, "Failed to add audio capture\n");
        goto error_free;
    }

    wav->cap = cap;
    s->opaque = wav;
    s->ops = wav_capture_ops;
    return 0;

error_free:
    g_free (wav->path);
    if (fclose (wav->f)) {
        monitor_printf (mon, "Failed to close wave file\nReason: %s\n",
                        strerror (errno));
    }
    g_free (wav);
    return -1;
}
