/*
 * Copyright (c) 2003, 2007, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

#define USE_ERROR
#define USE_TRACE

#include "PLATFORM_API_SolarisOS_Utils.h"
#include "DirectAudio.h"

#if USE_DAUDIO == TRUE


// The default buffer time
#define DEFAULT_PERIOD_TIME_MILLIS 50

///// implemented functions of DirectAudio.h

INT32 DAUDIO_GetDirectAudioDeviceCount() {
    return (INT32) getAudioDeviceCount();
}


INT32 DAUDIO_GetDirectAudioDeviceDescription(INT32 mixerIndex,
                                             DirectAudioDeviceDescription* description) {
    AudioDeviceDescription desc;

    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, TRUE)) {
        description->maxSimulLines = desc.maxSimulLines;
        strncpy(description->name, desc.name, DAUDIO_STRING_LENGTH-1);
        description->name[DAUDIO_STRING_LENGTH-1] = 0;
        strncpy(description->vendor, desc.vendor, DAUDIO_STRING_LENGTH-1);
        description->vendor[DAUDIO_STRING_LENGTH-1] = 0;
        strncpy(description->version, desc.version, DAUDIO_STRING_LENGTH-1);
        description->version[DAUDIO_STRING_LENGTH-1] = 0;
        /*strncpy(description->description, desc.description, DAUDIO_STRING_LENGTH-1);*/
        strncpy(description->description, "Solaris Mixer", DAUDIO_STRING_LENGTH-1);
        description->description[DAUDIO_STRING_LENGTH-1] = 0;
        return TRUE;
    }
    return FALSE;

}

#define MAX_SAMPLE_RATES   20

void DAUDIO_GetFormats(INT32 mixerIndex, INT32 deviceID, int isSource, void* creator) {
    int fd = -1;
    AudioDeviceDescription desc;
    am_sample_rates_t      *sr;
    /* hardcoded bits and channels */
    int bits[] = {8, 16};
    int bitsCount = 2;
    int channels[] = {1, 2};
    int channelsCount = 2;
    /* for querying sample rates */
    int err;
    int ch, b, s;

    TRACE2("DAUDIO_GetFormats, mixer %d, isSource=%d\n", mixerIndex, isSource);
    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
        fd = open(desc.pathctl, O_RDONLY);
    }
    if (fd < 0) {
        ERROR1("Couldn't open audio device ctl for device %d!\n", mixerIndex);
        return;
    }

    /* get sample rates */
    sr = (am_sample_rates_t*) malloc(AUDIO_MIXER_SAMP_RATES_STRUCT_SIZE(MAX_SAMPLE_RATES));
    if (sr == NULL) {
        ERROR1("DAUDIO_GetFormats: out of memory for mixer %d\n", (int) mixerIndex);
        close(fd);
        return;
    }

    sr->num_samp_rates = MAX_SAMPLE_RATES;
    sr->type = isSource?AUDIO_PLAY:AUDIO_RECORD;
    sr->samp_rates[0] = -2;
    err = ioctl(fd, AUDIO_MIXER_GET_SAMPLE_RATES, sr);
    if (err < 0) {
        ERROR1("  DAUDIO_GetFormats: AUDIO_MIXER_GET_SAMPLE_RATES failed for mixer %d!\n",
               (int)mixerIndex);
        ERROR2(" -> num_sample_rates=%d sample_rates[0] = %d\n",
               (int) sr->num_samp_rates,
               (int) sr->samp_rates[0]);
        /* Some Solaris 8 drivers fail for get sample rates!
         * Do as if we support all sample rates
         */
        sr->flags = MIXER_SR_LIMITS;
    }
    if ((sr->flags & MIXER_SR_LIMITS)
        || (sr->num_samp_rates > MAX_SAMPLE_RATES)) {
#ifdef USE_TRACE
        if ((sr->flags & MIXER_SR_LIMITS)) {
            TRACE1("  DAUDIO_GetFormats: floating sample rate allowed by mixer %d\n",
                   (int)mixerIndex);
        }
        if (sr->num_samp_rates > MAX_SAMPLE_RATES) {
            TRACE2("  DAUDIO_GetFormats: more than %d formats. Use -1 for sample rates mixer %d\n",
                   MAX_SAMPLE_RATES, (int)mixerIndex);
        }
#endif
        /*
         * Fake it to have only one sample rate: -1
         */
        sr->num_samp_rates = 1;
        sr->samp_rates[0] = -1;
    }
    close(fd);

    for (ch = 0; ch < channelsCount; ch++) {
        for (b = 0; b < bitsCount; b++) {
            for (s = 0; s < sr->num_samp_rates; s++) {
                DAUDIO_AddAudioFormat(creator,
                                      bits[b], /* significant bits */
                                      0, /* frameSize: let it be calculated */
                                      channels[ch],
                                      (float) ((int) sr->samp_rates[s]),
                                      DAUDIO_PCM, /* encoding - let's only do PCM */
                                      (bits[b] > 8)?TRUE:TRUE, /* isSigned */
#ifdef _LITTLE_ENDIAN
                                      FALSE /* little endian */
#else
                                      (bits[b] > 8)?TRUE:FALSE  /* big endian */
#endif
                                      );
            }
        }
    }
    free(sr);
}


typedef struct {
    int fd;
    audio_info_t info;
    int bufferSizeInBytes;
    int frameSize; /* storage size in Bytes */
    /* how many bytes were written or read */
    INT32 transferedBytes;
    /* if transferedBytes exceed 32-bit boundary,
     * it will be reset and positionOffset will receive
     * the offset
     */
    INT64 positionOffset;
} SolPcmInfo;


void* DAUDIO_Open(INT32 mixerIndex, INT32 deviceID, int isSource,
                  int encoding, float sampleRate, int sampleSizeInBits,
                  int frameSize, int channels,
                  int isSigned, int isBigEndian, int bufferSizeInBytes) {
    int err = 0;
    int openMode;
    AudioDeviceDescription desc;
    SolPcmInfo* info;

    TRACE0("> DAUDIO_Open\n");
    if (encoding != DAUDIO_PCM) {
        ERROR1(" DAUDIO_Open: invalid encoding %d\n", (int) encoding);
        return NULL;
    }

    info = (SolPcmInfo*) malloc(sizeof(SolPcmInfo));
    if (!info) {
        ERROR0("Out of memory\n");
        return NULL;
    }
    memset(info, 0, sizeof(SolPcmInfo));
    info->frameSize = frameSize;
    info->fd = -1;

    if (isSource) {
        openMode = O_WRONLY;
    } else {
        openMode = O_RDONLY;
    }

#ifndef __linux__
    /* blackdown does not use NONBLOCK */
    openMode |= O_NONBLOCK;
#endif

    if (getAudioDeviceDescriptionByIndex(mixerIndex, &desc, FALSE)) {
        info->fd = open(desc.path, openMode);
    }
    if (info->fd < 0) {
        ERROR1("Couldn't open audio device for mixer %d!\n", mixerIndex);
        free(info);
        return NULL;
    }
    /* set to multiple open */
    if (ioctl(info->fd, AUDIO_MIXER_MULTIPLE_OPEN, NULL) >= 0) {
        TRACE1("DAUDIO_Open: %s set to multiple open\n", desc.path);
    } else {
        ERROR1("DAUDIO_Open: ioctl AUDIO_MIXER_MULTIPLE_OPEN failed on %s!\n", desc.path);
    }

    AUDIO_INITINFO(&(info->info));
    /* need AUDIO_GETINFO ioctl to get this to work on solaris x86  */
    err = ioctl(info->fd, AUDIO_GETINFO, &(info->info));

    /* not valid to call AUDIO_SETINFO ioctl with all the fields from AUDIO_GETINFO. */
    AUDIO_INITINFO(&(info->info));

    if (isSource) {
        info->info.play.sample_rate = sampleRate;
        info->info.play.precision = sampleSizeInBits;
        info->info.play.channels = channels;
        info->info.play.encoding = AUDIO_ENCODING_LINEAR;
        info->info.play.buffer_size = bufferSizeInBytes;
        info->info.play.pause = 1;
    } else {
        info->info.record.sample_rate = sampleRate;
        info->info.record.precision = sampleSizeInBits;
        info->info.record.channels = channels;
        info->info.record.encoding = AUDIO_ENCODING_LINEAR;
        info->info.record.buffer_size = bufferSizeInBytes;
        info->info.record.pause = 1;
    }
    err = ioctl(info->fd, AUDIO_SETINFO,  &(info->info));
    if (err < 0) {
        ERROR0("DAUDIO_Open: could not set info!\n");
        DAUDIO_Close((void*) info, isSource);
        return NULL;
    }
    DAUDIO_Flush((void*) info, isSource);

    err = ioctl(info->fd, AUDIO_GETINFO, &(info->info));
    if (err >= 0) {
        if (isSource) {
            info->bufferSizeInBytes = info->info.play.buffer_size;
        } else {
            info->bufferSizeInBytes = info->info.record.buffer_size;
        }
        TRACE2("DAUDIO: buffersize in bytes: requested=%d, got %d\n",
               (int) bufferSizeInBytes,
               (int) info->bufferSizeInBytes);
    } else {
        ERROR0("DAUDIO_Open: cannot get info!\n");
        DAUDIO_Close((void*) info, isSource);
        return NULL;
    }
    TRACE0("< DAUDIO_Open: Opened device successfully.\n");
    return (void*) info;
}


int DAUDIO_Start(void* id, int isSource) {
    SolPcmInfo* info = (SolPcmInfo*) id;
    int err, modified;
    audio_info_t audioInfo;

    TRACE0("> DAUDIO_Start\n");

    AUDIO_INITINFO(&audioInfo);
    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
    if (err >= 0) {
        // unpause
        modified = FALSE;
        if (isSource && audioInfo.play.pause) {
            audioInfo.play.pause = 0;
            modified = TRUE;
        }
        if (!isSource && audioInfo.record.pause) {
            audioInfo.record.pause = 0;
            modified = TRUE;
        }
        if (modified) {
            err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
        }
    }

    TRACE1("< DAUDIO_Start %s\n", (err>=0)?"success":"error");
    return (err >= 0)?TRUE:FALSE;
}

int DAUDIO_Stop(void* id, int isSource) {
    SolPcmInfo* info = (SolPcmInfo*) id;
    int err, modified;
    audio_info_t audioInfo;

    TRACE0("> DAUDIO_Stop\n");

    AUDIO_INITINFO(&audioInfo);
    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
    if (err >= 0) {
        // pause
        modified = FALSE;
        if (isSource && !audioInfo.play.pause) {
            audioInfo.play.pause = 1;
            modified = TRUE;
        }
        if (!isSource && !audioInfo.record.pause) {
            audioInfo.record.pause = 1;
            modified = TRUE;
        }
        if (modified) {
            err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
        }
    }

    TRACE1("< DAUDIO_Stop %s\n", (err>=0)?"success":"error");
    return (err >= 0)?TRUE:FALSE;
}

void DAUDIO_Close(void* id, int isSource) {
    SolPcmInfo* info = (SolPcmInfo*) id;

    TRACE0("DAUDIO_Close\n");
    if (info != NULL) {
        if (info->fd >= 0) {
            DAUDIO_Flush(id, isSource);
            close(info->fd);
        }
        free(info);
    }
}

#ifndef USE_TRACE
/* close to 2^31 */
#define POSITION_MAX 2000000000
#else
/* for testing */
#define POSITION_MAX 1000000
#endif

void resetErrorFlagAndAdjustPosition(SolPcmInfo* info, int isSource, int count) {
    audio_info_t audioInfo;
    audio_prinfo_t* prinfo;
    int err;
    int offset = -1;
    int underrun = FALSE;
    int devBytes = 0;

    if (count > 0) {
        info->transferedBytes += count;

        if (isSource) {
            prinfo = &(audioInfo.play);
        } else {
            prinfo = &(audioInfo.record);
        }
        AUDIO_INITINFO(&audioInfo);
        err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
        if (err >= 0) {
            underrun = prinfo->error;
            devBytes = prinfo->samples * info->frameSize;
        }
        AUDIO_INITINFO(&audioInfo);
        if (underrun) {
            /* if an underrun occured, reset */
            ERROR1("DAUDIO_Write/Read: Underrun/overflow: adjusting positionOffset by %d:\n",
                   (devBytes - info->transferedBytes));
            ERROR1("    devBytes from %d to 0, ", devBytes);
            ERROR2(" positionOffset from %d to %d ",
                   (int) info->positionOffset,
                   (int) (info->positionOffset + info->transferedBytes));
            ERROR1(" transferedBytes from %d to 0\n",
                   (int) info->transferedBytes);
            prinfo->samples = 0;
            info->positionOffset += info->transferedBytes;
            info->transferedBytes = 0;
        }
        else if (info->transferedBytes > POSITION_MAX) {
            /* we will reset transferedBytes and
             * the samples field in prinfo
             */
            offset = devBytes;
            prinfo->samples = 0;
        }
        /* reset error flag */
        prinfo->error = 0;

        err = ioctl(info->fd, AUDIO_SETINFO, &audioInfo);
        if (err >= 0) {
            if (offset > 0) {
                /* upon exit of AUDIO_SETINFO, the samples parameter
                 * was set to the previous value. This is our
                 * offset.
                 */
                TRACE1("Adjust samplePos: offset=%d, ", (int) offset);
                TRACE2("transferedBytes=%d -> %d, ",
                       (int) info->transferedBytes,
                       (int) (info->transferedBytes - offset));
                TRACE2("positionOffset=%d -> %d\n",
                       (int) (info->positionOffset),
                       (int) (((int) info->positionOffset) + offset));
                info->transferedBytes -= offset;
                info->positionOffset += offset;
            }
        } else {
            ERROR0("DAUDIO: resetErrorFlagAndAdjustPosition ioctl failed!\n");
        }
    }
}

// returns -1 on error
int DAUDIO_Write(void* id, char* data, int byteSize) {
    SolPcmInfo* info = (SolPcmInfo*) id;
    int ret = -1;

    TRACE1("> DAUDIO_Write %d bytes\n", byteSize);
    if (info!=NULL) {
        ret = write(info->fd, data, byteSize);
        resetErrorFlagAndAdjustPosition(info, TRUE, ret);
        /* sets ret to -1 if buffer full, no error! */
        if (ret < 0) {
            ret = 0;
        }
    }
    TRACE1("< DAUDIO_Write: returning %d bytes.\n", ret);
    return ret;
}

// returns -1 on error
int DAUDIO_Read(void* id, char* data, int byteSize) {
    SolPcmInfo* info = (SolPcmInfo*) id;
    int ret = -1;

    TRACE1("> DAUDIO_Read %d bytes\n", byteSize);
    if (info != NULL) {
        ret = read(info->fd, data, byteSize);
        resetErrorFlagAndAdjustPosition(info, TRUE, ret);
        /* sets ret to -1 if buffer full, no error! */
        if (ret < 0) {
            ret = 0;
        }
    }
    TRACE1("< DAUDIO_Read: returning %d bytes.\n", ret);
    return ret;
}


int DAUDIO_GetBufferSize(void* id, int isSource) {
    SolPcmInfo* info = (SolPcmInfo*) id;
    if (info) {
        return info->bufferSizeInBytes;
    }
    return 0;
}

int DAUDIO_StillDraining(void* id, int isSource) {
    SolPcmInfo* info = (SolPcmInfo*) id;
    audio_info_t audioInfo;
    audio_prinfo_t* prinfo;
    int ret = FALSE;

    if (info!=NULL) {
        if (isSource) {
            prinfo = &(audioInfo.play);
        } else {
            prinfo = &(audioInfo.record);
        }
        /* check error flag */
        AUDIO_INITINFO(&audioInfo);
        ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
        ret = (prinfo->error != 0)?FALSE:TRUE;
    }
    return ret;
}


int getDevicePosition(SolPcmInfo* info, int isSource) {
    audio_info_t audioInfo;
    audio_prinfo_t* prinfo;
    int err;

    if (isSource) {
        prinfo = &(audioInfo.play);
    } else {
        prinfo = &(audioInfo.record);
    }
    AUDIO_INITINFO(&audioInfo);
    err = ioctl(info->fd, AUDIO_GETINFO, &audioInfo);
    if (err >= 0) {
        /*TRACE2("---> device paused: %d  eof=%d\n",
               prinfo->pause, prinfo->eof);
        */
        return (int) (prinfo->samples * info->frameSize);
    }
    ERROR0("DAUDIO: getDevicePosition: ioctl failed!\n");
    return -1;
}

int DAUDIO_Flush(void* id, int isSource) {
    SolPcmInfo* info = (SolPcmInfo*) id;
    int err = -1;
    int pos;

    TRACE0("DAUDIO_Flush\n");
    if (info) {
        if (isSource) {
            err = ioctl(info->fd, I_FLUSH, FLUSHW);
        } else {
            err = ioctl(info->fd, I_FLUSH, FLUSHR);
        }
        if (err >= 0) {
            /* resets the transferedBytes parameter to
             * the current samples count of the device
             */
            pos = getDevicePosition(info, isSource);
            if (pos >= 0) {
                info->transferedBytes = pos;
            }
        }
    }
    if (err < 0) {
        ERROR0("ERROR in DAUDIO_Flush\n");
    }
    return (err < 0)?FALSE:TRUE;
}

int DAUDIO_GetAvailable(void* id, int isSource) {
    SolPcmInfo* info = (SolPcmInfo*) id;
    int ret = 0;
    int pos;

    if (info) {
        /* unfortunately, the STREAMS architecture
         * seems to not have a method for querying
         * the available bytes to read/write!
         * estimate it...
         */
        pos = getDevicePosition(info, isSource);
        if (pos >= 0) {
            if (isSource) {
                /* we usually have written more bytes
                 * to the queue than the device position should be
                 */
                ret = (info->bufferSizeInBytes) - (info->transferedBytes - pos);
            } else {
                /* for record, the device stream should
                 * be usually ahead of our read actions
                 */
                ret = pos - info->transferedBytes;
            }
            if (ret > info->bufferSizeInBytes) {
                ERROR2("DAUDIO_GetAvailable: available=%d, too big at bufferSize=%d!\n",
                       (int) ret, (int) info->bufferSizeInBytes);
                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
                       (int) pos, (int) info->transferedBytes);
                ret = info->bufferSizeInBytes;
            }
            else if (ret < 0) {
                ERROR1("DAUDIO_GetAvailable: available=%d, in theory not possible!\n",
                       (int) ret);
                ERROR2("                     devicePos=%d, transferedBytes=%d\n",
                       (int) pos, (int) info->transferedBytes);
                ret = 0;
            }
        }
    }

    TRACE1("DAUDIO_GetAvailable returns %d bytes\n", ret);
    return ret;
}

INT64 DAUDIO_GetBytePosition(void* id, int isSource, INT64 javaBytePos) {
    SolPcmInfo* info = (SolPcmInfo*) id;
    int ret;
    int pos;
    INT64 result = javaBytePos;

    if (info) {
        pos = getDevicePosition(info, isSource);
        if (pos >= 0) {
            result = info->positionOffset + pos;
        }
    }

    //printf("getbyteposition: javaBytePos=%d , return=%d\n", (int) javaBytePos, (int) result);
    return result;
}


void DAUDIO_SetBytePosition(void* id, int isSource, INT64 javaBytePos) {
    SolPcmInfo* info = (SolPcmInfo*) id;
    int ret;
    int pos;

    if (info) {
        pos = getDevicePosition(info, isSource);
        if (pos >= 0) {
            info->positionOffset = javaBytePos - pos;
        }
    }
}

int DAUDIO_RequiresServicing(void* id, int isSource) {
    // never need servicing on Solaris
    return FALSE;
}

void DAUDIO_Service(void* id, int isSource) {
    // never need servicing on Solaris
}


#endif // USE_DAUDIO
