/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <audio_utils/sndfile.h>
#include <audio_utils/primitives.h>
#ifdef HAVE_STDERR
#include <stdio.h>
#endif
#include <string.h>
#include <errno.h>

#define WAVE_FORMAT_PCM         1
#define WAVE_FORMAT_IEEE_FLOAT  3
#define WAVE_FORMAT_EXTENSIBLE  0xFFFE

struct SNDFILE_ {
    int mode;
    uint8_t *temp;  // realloc buffer used for shrinking 16 bits to 8 bits and byte-swapping
    FILE *stream;
    size_t bytesPerFrame;
    size_t remaining;   // frames unread for SFM_READ, frames written for SFM_WRITE
    SF_INFO info;
};

static unsigned little2u(unsigned char *ptr)
{
    return (ptr[1] << 8) + ptr[0];
}

static unsigned little4u(unsigned char *ptr)
{
    return (ptr[3] << 24) + (ptr[2] << 16) + (ptr[1] << 8) + ptr[0];
}

static int isLittleEndian(void)
{
    static const short one = 1;
    return *((const char *) &one) == 1;
}

// "swab" conflicts with OS X <string.h>
static void my_swab(short *ptr, size_t numToSwap)
{
    while (numToSwap > 0) {
        *ptr = little2u((unsigned char *) ptr);
        --numToSwap;
        ++ptr;
    }
}

static SNDFILE *sf_open_read(const char *path, SF_INFO *info)
{
    FILE *stream = fopen(path, "rb");
    if (stream == NULL) {
#ifdef HAVE_STDERR
        fprintf(stderr, "fopen %s failed errno %d\n", path, errno);
#endif
        return NULL;
    }

    SNDFILE *handle = (SNDFILE *) malloc(sizeof(SNDFILE));
    handle->mode = SFM_READ;
    handle->temp = NULL;
    handle->stream = stream;
    handle->info.format = SF_FORMAT_WAV;

    // don't attempt to parse all valid forms, just the most common ones
    unsigned char wav[12];
    size_t actual;
    actual = fread(wav, sizeof(char), sizeof(wav), stream);
    if (actual < 12) {
#ifdef HAVE_STDERR
        fprintf(stderr, "actual %zu < 44\n", actual);
#endif
        goto close;
    }
    if (memcmp(wav, "RIFF", 4)) {
#ifdef HAVE_STDERR
        fprintf(stderr, "wav != RIFF\n");
#endif
        goto close;
    }
    unsigned riffSize = little4u(&wav[4]);
    if (riffSize < 4) {
#ifdef HAVE_STDERR
        fprintf(stderr, "riffSize %u < 4\n", riffSize);
#endif
        goto close;
    }
    if (memcmp(&wav[8], "WAVE", 4)) {
#ifdef HAVE_STDERR
        fprintf(stderr, "missing WAVE\n");
#endif
        goto close;
    }
    size_t remaining = riffSize - 4;
    int hadFmt = 0;
    int hadData = 0;
    long dataTell = 0L;
    while (remaining >= 8) {
        unsigned char chunk[8];
        actual = fread(chunk, sizeof(char), sizeof(chunk), stream);
        if (actual != sizeof(chunk)) {
#ifdef HAVE_STDERR
            fprintf(stderr, "actual %zu != %zu\n", actual, sizeof(chunk));
#endif
            goto close;
        }
        remaining -= 8;
        unsigned chunkSize = little4u(&chunk[4]);
        if (chunkSize > remaining) {
#ifdef HAVE_STDERR
            fprintf(stderr, "chunkSize %u > remaining %zu\n", chunkSize, remaining);
#endif
            goto close;
        }
        if (!memcmp(&chunk[0], "fmt ", 4)) {
            if (hadFmt) {
#ifdef HAVE_STDERR
                fprintf(stderr, "multiple fmt\n");
#endif
                goto close;
            }
            if (chunkSize < 2) {
#ifdef HAVE_STDERR
                fprintf(stderr, "chunkSize %u < 2\n", chunkSize);
#endif
                goto close;
            }
            unsigned char fmt[40];
            actual = fread(fmt, sizeof(char), 2, stream);
            if (actual != 2) {
#ifdef HAVE_STDERR
                fprintf(stderr, "actual %zu != 2\n", actual);
#endif
                goto close;
            }
            unsigned format = little2u(&fmt[0]);
            size_t minSize = 0;
            switch (format) {
            case WAVE_FORMAT_PCM:
            case WAVE_FORMAT_IEEE_FLOAT:
                minSize = 16;
                break;
            case WAVE_FORMAT_EXTENSIBLE:
                minSize = 40;
                break;
            default:
#ifdef HAVE_STDERR
                fprintf(stderr, "unsupported format %u\n", format);
#endif
                goto close;
            }
            if (chunkSize < minSize) {
#ifdef HAVE_STDERR
                fprintf(stderr, "chunkSize %u < minSize %zu\n", chunkSize, minSize);
#endif
                goto close;
            }
            actual = fread(&fmt[2], sizeof(char), minSize - 2, stream);
            if (actual != minSize - 2) {
#ifdef HAVE_STDERR
                fprintf(stderr, "actual %zu != %zu\n", actual, minSize - 16);
#endif
                goto close;
            }
            if (chunkSize > minSize) {
                fseek(stream, (long) (chunkSize - minSize), SEEK_CUR);
            }
            unsigned channels = little2u(&fmt[2]);
            // FIXME FCC_8
            if (channels != 1 && channels != 2 && channels != 4 && channels != 6 && channels != 8) {
#ifdef HAVE_STDERR
                fprintf(stderr, "unsupported channels %u\n", channels);
#endif
                goto close;
            }
            unsigned samplerate = little4u(&fmt[4]);
            if (samplerate == 0) {
#ifdef HAVE_STDERR
                fprintf(stderr, "samplerate %u == 0\n", samplerate);
#endif
                goto close;
            }
            // ignore byte rate
            // ignore block alignment
            unsigned bitsPerSample = little2u(&fmt[14]);
            if (bitsPerSample != 8 && bitsPerSample != 16 && bitsPerSample != 24 &&
                    bitsPerSample != 32) {
#ifdef HAVE_STDERR
                fprintf(stderr, "bitsPerSample %u != 8 or 16 or 24 or 32\n", bitsPerSample);
#endif
                goto close;
            }
            unsigned bytesPerFrame = (bitsPerSample >> 3) * channels;
            handle->bytesPerFrame = bytesPerFrame;
            handle->info.samplerate = samplerate;
            handle->info.channels = channels;
            switch (bitsPerSample) {
            case 8:
                handle->info.format |= SF_FORMAT_PCM_U8;
                break;
            case 16:
                handle->info.format |= SF_FORMAT_PCM_16;
                break;
            case 24:
                handle->info.format |= SF_FORMAT_PCM_24;
                break;
            case 32:
                if (format == WAVE_FORMAT_IEEE_FLOAT)
                    handle->info.format |= SF_FORMAT_FLOAT;
                else
                    handle->info.format |= SF_FORMAT_PCM_32;
                break;
            }
            hadFmt = 1;
        } else if (!memcmp(&chunk[0], "data", 4)) {
            if (!hadFmt) {
#ifdef HAVE_STDERR
                fprintf(stderr, "data not preceded by fmt\n");
#endif
                goto close;
            }
            if (hadData) {
#ifdef HAVE_STDERR
                fprintf(stderr, "multiple data\n");
#endif
                goto close;
            }
            handle->remaining = chunkSize / handle->bytesPerFrame;
            handle->info.frames = handle->remaining;
            dataTell = ftell(stream);
            if (chunkSize > 0) {
                fseek(stream, (long) chunkSize, SEEK_CUR);
            }
            hadData = 1;
        } else if (!memcmp(&chunk[0], "fact", 4)) {
            // ignore fact
            if (chunkSize > 0) {
                fseek(stream, (long) chunkSize, SEEK_CUR);
            }
        } else {
            // ignore unknown chunk
#ifdef HAVE_STDERR
            fprintf(stderr, "ignoring unknown chunk %c%c%c%c\n",
                    chunk[0], chunk[1], chunk[2], chunk[3]);
#endif
            if (chunkSize > 0) {
                fseek(stream, (long) chunkSize, SEEK_CUR);
            }
        }
        remaining -= chunkSize;
    }
    if (remaining > 0) {
#ifdef HAVE_STDERR
        fprintf(stderr, "partial chunk at end of RIFF, remaining %zu\n", remaining);
#endif
        goto close;
    }
    if (!hadData) {
#ifdef HAVE_STDERR
        fprintf(stderr, "missing data\n");
#endif
        goto close;
    }
    (void) fseek(stream, dataTell, SEEK_SET);
    *info = handle->info;
    return handle;

close:
    free(handle);
    fclose(stream);
    return NULL;
}

static void write4u(unsigned char *ptr, unsigned u)
{
    ptr[0] = u;
    ptr[1] = u >> 8;
    ptr[2] = u >> 16;
    ptr[3] = u >> 24;
}

static SNDFILE *sf_open_write(const char *path, SF_INFO *info)
{
    int sub = info->format & SF_FORMAT_SUBMASK;
    if (!(
            (info->samplerate > 0) &&
            // FIXME FCC_8
            (info->channels > 0 && info->channels <= 8) &&
            ((info->format & SF_FORMAT_TYPEMASK) == SF_FORMAT_WAV) &&
            (sub == SF_FORMAT_PCM_16 || sub == SF_FORMAT_PCM_U8 || sub == SF_FORMAT_FLOAT ||
                sub == SF_FORMAT_PCM_24 || sub == SF_FORMAT_PCM_32)
          )) {
        return NULL;
    }
    FILE *stream = fopen(path, "w+b");
    if (stream == NULL) {
#ifdef HAVE_STDERR
        fprintf(stderr, "fopen %s failed errno %d\n", path, errno);
#endif
        return NULL;
    }
    unsigned char wav[58];
    memset(wav, 0, sizeof(wav));
    memcpy(wav, "RIFF", 4);
    memcpy(&wav[8], "WAVEfmt ", 8);
    if (sub == SF_FORMAT_FLOAT) {
        wav[4] = 50;    // riffSize
        wav[16] = 18;   // fmtSize
        wav[20] = WAVE_FORMAT_IEEE_FLOAT;
    } else {
        wav[4] = 36;    // riffSize
        wav[16] = 16;   // fmtSize
        wav[20] = WAVE_FORMAT_PCM;
    }
    wav[22] = info->channels;
    write4u(&wav[24], info->samplerate);
    unsigned bitsPerSample;
    switch (sub) {
    case SF_FORMAT_PCM_16:
        bitsPerSample = 16;
        break;
    case SF_FORMAT_PCM_U8:
        bitsPerSample = 8;
        break;
    case SF_FORMAT_FLOAT:
        bitsPerSample = 32;
        break;
    case SF_FORMAT_PCM_24:
        bitsPerSample = 24;
        break;
    case SF_FORMAT_PCM_32:
        bitsPerSample = 32;
        break;
    default:    // not reachable
        bitsPerSample = 0;
        break;
    }
    unsigned blockAlignment = (bitsPerSample >> 3) * info->channels;
    unsigned byteRate = info->samplerate * blockAlignment;
    write4u(&wav[28], byteRate);
    wav[32] = blockAlignment;
    wav[34] = bitsPerSample;
    size_t extra = 0;
    if (sub == SF_FORMAT_FLOAT) {
        memcpy(&wav[38], "fact", 4);
        wav[42] = 4;
        memcpy(&wav[50], "data", 4);
        extra = 14;
    } else
        memcpy(&wav[36], "data", 4);
    // dataSize is initially zero
    (void) fwrite(wav, 44 + extra, 1, stream);
    SNDFILE *handle = (SNDFILE *) malloc(sizeof(SNDFILE));
    handle->mode = SFM_WRITE;
    handle->temp = NULL;
    handle->stream = stream;
    handle->bytesPerFrame = blockAlignment;
    handle->remaining = 0;
    handle->info = *info;
    return handle;
}

SNDFILE *sf_open(const char *path, int mode, SF_INFO *info)
{
    if (path == NULL || info == NULL) {
#ifdef HAVE_STDERR
        fprintf(stderr, "path=%p info=%p\n", path, info);
#endif
        return NULL;
    }
    switch (mode) {
    case SFM_READ:
        return sf_open_read(path, info);
    case SFM_WRITE:
        return sf_open_write(path, info);
    default:
#ifdef HAVE_STDERR
        fprintf(stderr, "mode=%d\n", mode);
#endif
        return NULL;
    }
}

void sf_close(SNDFILE *handle)
{
    if (handle == NULL)
        return;
    free(handle->temp);
    if (handle->mode == SFM_WRITE) {
        (void) fflush(handle->stream);
        rewind(handle->stream);
        unsigned char wav[58];
        size_t extra = (handle->info.format & SF_FORMAT_SUBMASK) == SF_FORMAT_FLOAT ? 14 : 0;
        (void) fread(wav, 44 + extra, 1, handle->stream);
        unsigned dataSize = handle->remaining * handle->bytesPerFrame;
        write4u(&wav[4], dataSize + 36 + extra);    // riffSize
        write4u(&wav[40 + extra], dataSize);        // dataSize
        rewind(handle->stream);
        (void) fwrite(wav, 44 + extra, 1, handle->stream);
    }
    (void) fclose(handle->stream);
    free(handle);
}

sf_count_t sf_readf_short(SNDFILE *handle, short *ptr, sf_count_t desiredFrames)
{
    if (handle == NULL || handle->mode != SFM_READ || ptr == NULL || !handle->remaining ||
            desiredFrames <= 0) {
        return 0;
    }
    if (handle->remaining < (size_t) desiredFrames) {
        desiredFrames = handle->remaining;
    }
    // does not check for numeric overflow
    size_t desiredBytes = desiredFrames * handle->bytesPerFrame;
    size_t actualBytes;
    void *temp = NULL;
    unsigned format = handle->info.format & SF_FORMAT_SUBMASK;
    if (format == SF_FORMAT_PCM_32 || format == SF_FORMAT_FLOAT || format == SF_FORMAT_PCM_24) {
        temp = malloc(desiredBytes);
        actualBytes = fread(temp, sizeof(char), desiredBytes, handle->stream);
    } else {
        actualBytes = fread(ptr, sizeof(char), desiredBytes, handle->stream);
    }
    size_t actualFrames = actualBytes / handle->bytesPerFrame;
    handle->remaining -= actualFrames;
    switch (format) {
    case SF_FORMAT_PCM_U8:
        memcpy_to_i16_from_u8(ptr, (unsigned char *) ptr, actualFrames * handle->info.channels);
        break;
    case SF_FORMAT_PCM_16:
        if (!isLittleEndian())
            my_swab(ptr, actualFrames * handle->info.channels);
        break;
    case SF_FORMAT_PCM_32:
        memcpy_to_i16_from_i32(ptr, (const int *) temp, actualFrames * handle->info.channels);
        free(temp);
        break;
    case SF_FORMAT_FLOAT:
        memcpy_to_i16_from_float(ptr, (const float *) temp, actualFrames * handle->info.channels);
        free(temp);
        break;
    case SF_FORMAT_PCM_24:
        memcpy_to_i16_from_p24(ptr, (const uint8_t *) temp, actualFrames * handle->info.channels);
        free(temp);
        break;
    default:
        memset(ptr, 0, actualFrames * handle->info.channels * sizeof(short));
        break;
    }
    return actualFrames;
}

sf_count_t sf_readf_float(SNDFILE *handle, float *ptr, sf_count_t desiredFrames)
{
    if (handle == NULL || handle->mode != SFM_READ || ptr == NULL || !handle->remaining ||
            desiredFrames <= 0) {
        return 0;
    }
    if (handle->remaining < (size_t) desiredFrames) {
        desiredFrames = handle->remaining;
    }
    // does not check for numeric overflow
    size_t desiredBytes = desiredFrames * handle->bytesPerFrame;
    size_t actualBytes;
    void *temp = NULL;
    unsigned format = handle->info.format & SF_FORMAT_SUBMASK;
    if (format == SF_FORMAT_PCM_16 || format == SF_FORMAT_PCM_U8 || format == SF_FORMAT_PCM_24) {
        temp = malloc(desiredBytes);
        actualBytes = fread(temp, sizeof(char), desiredBytes, handle->stream);
    } else {
        actualBytes = fread(ptr, sizeof(char), desiredBytes, handle->stream);
    }
    size_t actualFrames = actualBytes / handle->bytesPerFrame;
    handle->remaining -= actualFrames;
    switch (format) {
    case SF_FORMAT_PCM_U8:
#if 0
        // TODO - implement
        memcpy_to_float_from_u8(ptr, (const unsigned char *) temp,
                actualFrames * handle->info.channels);
#endif
        free(temp);
        break;
    case SF_FORMAT_PCM_16:
        memcpy_to_float_from_i16(ptr, (const short *) temp, actualFrames * handle->info.channels);
        free(temp);
        break;
    case SF_FORMAT_PCM_32:
        memcpy_to_float_from_i32(ptr, (const int *) ptr, actualFrames * handle->info.channels);
        break;
    case SF_FORMAT_FLOAT:
        break;
    case SF_FORMAT_PCM_24:
        memcpy_to_float_from_p24(ptr, (const uint8_t *) temp, actualFrames * handle->info.channels);
        free(temp);
        break;
    default:
        memset(ptr, 0, actualFrames * handle->info.channels * sizeof(float));
        break;
    }
    return actualFrames;
}

sf_count_t sf_readf_int(SNDFILE *handle, int *ptr, sf_count_t desiredFrames)
{
    if (handle == NULL || handle->mode != SFM_READ || ptr == NULL || !handle->remaining ||
            desiredFrames <= 0) {
        return 0;
    }
    if (handle->remaining < (size_t) desiredFrames) {
        desiredFrames = handle->remaining;
    }
    // does not check for numeric overflow
    size_t desiredBytes = desiredFrames * handle->bytesPerFrame;
    void *temp = NULL;
    unsigned format = handle->info.format & SF_FORMAT_SUBMASK;
    size_t actualBytes;
    if (format == SF_FORMAT_PCM_16 || format == SF_FORMAT_PCM_U8 || format == SF_FORMAT_PCM_24) {
        temp = malloc(desiredBytes);
        actualBytes = fread(temp, sizeof(char), desiredBytes, handle->stream);
    } else {
        actualBytes = fread(ptr, sizeof(char), desiredBytes, handle->stream);
    }
    size_t actualFrames = actualBytes / handle->bytesPerFrame;
    handle->remaining -= actualFrames;
    switch (format) {
    case SF_FORMAT_PCM_U8:
#if 0
        // TODO - implement
        memcpy_to_i32_from_u8(ptr, (const unsigned char *) temp,
                actualFrames * handle->info.channels);
#endif
        free(temp);
        break;
    case SF_FORMAT_PCM_16:
        memcpy_to_i32_from_i16(ptr, (const short *) temp, actualFrames * handle->info.channels);
        free(temp);
        break;
    case SF_FORMAT_PCM_32:
        break;
    case SF_FORMAT_FLOAT:
        memcpy_to_i32_from_float(ptr, (const float *) ptr, actualFrames * handle->info.channels);
        break;
    case SF_FORMAT_PCM_24:
        memcpy_to_i32_from_p24(ptr, (const uint8_t *) temp, actualFrames * handle->info.channels);
        free(temp);
        break;
    default:
        memset(ptr, 0, actualFrames * handle->info.channels * sizeof(int));
        break;
    }
    return actualFrames;
}

sf_count_t sf_writef_short(SNDFILE *handle, const short *ptr, sf_count_t desiredFrames)
{
    if (handle == NULL || handle->mode != SFM_WRITE || ptr == NULL || desiredFrames <= 0)
        return 0;
    size_t desiredBytes = desiredFrames * handle->bytesPerFrame;
    size_t actualBytes = 0;
    switch (handle->info.format & SF_FORMAT_SUBMASK) {
    case SF_FORMAT_PCM_U8:
        handle->temp = realloc(handle->temp, desiredBytes);
        memcpy_to_u8_from_i16(handle->temp, ptr, desiredBytes);
        actualBytes = fwrite(handle->temp, sizeof(char), desiredBytes, handle->stream);
        break;
    case SF_FORMAT_PCM_16:
        // does not check for numeric overflow
        if (isLittleEndian()) {
            actualBytes = fwrite(ptr, sizeof(char), desiredBytes, handle->stream);
        } else {
            handle->temp = realloc(handle->temp, desiredBytes);
            memcpy(handle->temp, ptr, desiredBytes);
            my_swab((short *) handle->temp, desiredFrames * handle->info.channels);
            actualBytes = fwrite(handle->temp, sizeof(char), desiredBytes, handle->stream);
        }
        break;
    case SF_FORMAT_FLOAT:
        handle->temp = realloc(handle->temp, desiredBytes);
        memcpy_to_float_from_i16((float *) handle->temp, ptr,
                desiredFrames * handle->info.channels);
        actualBytes = fwrite(handle->temp, sizeof(char), desiredBytes, handle->stream);
        break;
    default:
        break;
    }
    size_t actualFrames = actualBytes / handle->bytesPerFrame;
    handle->remaining += actualFrames;
    return actualFrames;
}

sf_count_t sf_writef_float(SNDFILE *handle, const float *ptr, sf_count_t desiredFrames)
{
    if (handle == NULL || handle->mode != SFM_WRITE || ptr == NULL || desiredFrames <= 0)
        return 0;
    size_t desiredBytes = desiredFrames * handle->bytesPerFrame;
    size_t actualBytes = 0;
    switch (handle->info.format & SF_FORMAT_SUBMASK) {
    case SF_FORMAT_FLOAT:
        actualBytes = fwrite(ptr, sizeof(char), desiredBytes, handle->stream);
        break;
    case SF_FORMAT_PCM_16:
        handle->temp = realloc(handle->temp, desiredBytes);
        memcpy_to_i16_from_float((short *) handle->temp, ptr,
                desiredFrames * handle->info.channels);
        actualBytes = fwrite(handle->temp, sizeof(char), desiredBytes, handle->stream);
        break;
    case SF_FORMAT_PCM_U8:  // transcoding from float to byte not yet implemented
    default:
        break;
    }
    size_t actualFrames = actualBytes / handle->bytesPerFrame;
    handle->remaining += actualFrames;
    return actualFrames;
}

sf_count_t sf_writef_int(SNDFILE *handle, const int *ptr, sf_count_t desiredFrames)
{
    if (handle == NULL || handle->mode != SFM_WRITE || ptr == NULL || desiredFrames <= 0)
        return 0;
    size_t desiredBytes = desiredFrames * handle->bytesPerFrame;
    size_t actualBytes = 0;
    switch (handle->info.format & SF_FORMAT_SUBMASK) {
    case SF_FORMAT_PCM_32:
        actualBytes = fwrite(ptr, sizeof(char), desiredBytes, handle->stream);
        break;
    default:    // transcoding from other formats not yet implemented
        break;
    }
    size_t actualFrames = actualBytes / handle->bytesPerFrame;
    handle->remaining += actualFrames;
    return actualFrames;
}
