/*
** Copyright 2007, 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.
*/

//#define LOG_NDEBUG 0
#define LOG_TAG "VorbisPlayer"
#include "utils/Log.h"

#include <stdio.h>
#include <assert.h>
#include <limits.h>
#include <unistd.h>
#include <fcntl.h>
#include <sched.h>
#include <sys/types.h>
#include <sys/stat.h>


#include "VorbisPlayer.h"

#ifdef HAVE_GETTID
static pid_t myTid() { return gettid(); }
#else
static pid_t myTid() { return getpid(); }
#endif

// ----------------------------------------------------------------------------

namespace android {

// ----------------------------------------------------------------------------

// TODO: Determine appropriate return codes
static status_t ERROR_NOT_OPEN = -1;
static status_t ERROR_OPEN_FAILED = -2;
static status_t ERROR_ALLOCATE_FAILED = -4;
static status_t ERROR_NOT_SUPPORTED = -8;
static status_t ERROR_NOT_READY = -16;
static status_t STATE_INIT = 0;
static status_t STATE_ERROR = 1;
static status_t STATE_OPEN = 2;


VorbisPlayer::VorbisPlayer() :
    mAudioBuffer(NULL), mPlayTime(-1), mDuration(-1), mState(STATE_ERROR),
    mStreamType(AudioSystem::MUSIC), mLoop(false), mAndroidLoop(false),
    mExit(false), mPaused(false), mRender(false), mRenderTid(-1)
{
    LOGV("constructor\n");
    memset(&mVorbisFile, 0, sizeof mVorbisFile);
}

void VorbisPlayer::onFirstRef()
{
    LOGV("onFirstRef");
    // create playback thread
    Mutex::Autolock l(mMutex);
    createThreadEtc(renderThread, this, "vorbis decoder", ANDROID_PRIORITY_AUDIO);
    mCondition.wait(mMutex);
    if (mRenderTid > 0) {
        LOGV("render thread(%d) started", mRenderTid);
        mState = STATE_INIT;
    }
}

status_t VorbisPlayer::initCheck()
{
    if (mState != STATE_ERROR) return NO_ERROR;
    return ERROR_NOT_READY;
}

VorbisPlayer::~VorbisPlayer() {
    LOGV("VorbisPlayer destructor\n");
    release();
}

status_t VorbisPlayer::setDataSource(const char* path)
{
    return setdatasource(path, -1, 0, 0x7ffffffffffffffLL); // intentionally less than LONG_MAX
}

status_t VorbisPlayer::setDataSource(int fd, int64_t offset, int64_t length)
{
    return setdatasource(NULL, fd, offset, length);
}

size_t VorbisPlayer::vp_fread(void *buf, size_t size, size_t nmemb, void *me) {
    VorbisPlayer *self = (VorbisPlayer*) me;

    long curpos = vp_ftell(me);
    while (nmemb != 0 && (curpos + size * nmemb) > self->mLength) {
        nmemb--;
    }
    return fread(buf, size, nmemb, self->mFile);
}

int VorbisPlayer::vp_fseek(void *me, ogg_int64_t off, int whence) {
    VorbisPlayer *self = (VorbisPlayer*) me;
    if (whence == SEEK_SET)
        return fseek(self->mFile, off + self->mOffset, whence);
    else if (whence == SEEK_CUR)
        return fseek(self->mFile, off, whence);
    else if (whence == SEEK_END)
        return fseek(self->mFile, self->mOffset + self->mLength + off, SEEK_SET);
    return -1;
}

int VorbisPlayer::vp_fclose(void *me) {
    LOGV("vp_fclose");
    VorbisPlayer *self = (VorbisPlayer*) me;
    int ret = fclose (self->mFile);
    self->mFile = NULL;
    return ret;
}

long VorbisPlayer::vp_ftell(void *me) {
    VorbisPlayer *self = (VorbisPlayer*) me;
    return ftell(self->mFile) - self->mOffset;
}

status_t VorbisPlayer::setdatasource(const char *path, int fd, int64_t offset, int64_t length)
{
    LOGV("setDataSource url=%s, fd=%d\n", path, fd);

    // file still open?
    Mutex::Autolock l(mMutex);
    if (mState == STATE_OPEN) {
        reset_nosync();
    }

    // open file and set paused state
    if (path) {
        mFile = fopen(path, "r");
    } else {
        mFile = fdopen(dup(fd), "r");
    }
    if (mFile == NULL) {
        return ERROR_OPEN_FAILED;
    }

    struct stat sb;
    int ret;
    if (path) {
        ret = stat(path, &sb);
    } else {
        ret = fstat(fd, &sb);
    }
    if (ret != 0) {
        mState = STATE_ERROR;
        fclose(mFile);
        return ERROR_OPEN_FAILED;
    }
    if (sb.st_size > (length + offset)) {
        mLength = length;
    } else {
        mLength = sb.st_size - offset;
    }

    ov_callbacks callbacks = {
        (size_t (*)(void *, size_t, size_t, void *))  vp_fread,
        (int (*)(void *, ogg_int64_t, int))           vp_fseek,
        (int (*)(void *))                             vp_fclose,
        (long (*)(void *))                            vp_ftell
    };

    mOffset = offset;
    fseek(mFile, offset, SEEK_SET);

    int result = ov_open_callbacks(this, &mVorbisFile, NULL, 0, callbacks);
    if (result < 0) {
        LOGE("ov_open() failed: [%d]\n", (int)result);
        mState = STATE_ERROR;
        fclose(mFile);
        return ERROR_OPEN_FAILED;
    }

    // look for the android loop tag  (for ringtones)
    char **ptr = ov_comment(&mVorbisFile,-1)->user_comments;
    while(*ptr) {
        // does the comment start with ANDROID_LOOP_TAG
        if(strncmp(*ptr, ANDROID_LOOP_TAG, strlen(ANDROID_LOOP_TAG)) == 0) {
            // read the value of the tag
            char *val = *ptr + strlen(ANDROID_LOOP_TAG) + 1;
            mAndroidLoop = (strncmp(val, "true", 4) == 0);
        }
        // we keep parsing even after finding one occurence of ANDROID_LOOP_TAG,
        // as we could find another one  (the tag might have been appended more than once).
        ++ptr;
    }
    LOGV_IF(mAndroidLoop, "looped sound");

    mState = STATE_OPEN;
    return NO_ERROR;
}

status_t VorbisPlayer::prepare()
{
    LOGV("prepare\n");
    if (mState != STATE_OPEN ) {
        return ERROR_NOT_OPEN;
    }
    return NO_ERROR;
}

status_t VorbisPlayer::prepareAsync() {
    LOGV("prepareAsync\n");
    // can't hold the lock here because of the callback
    // it's safe because we don't change state
    if (mState != STATE_OPEN ) {
        sendEvent(MEDIA_ERROR);
        return NO_ERROR;
    }
    sendEvent(MEDIA_PREPARED);
    return NO_ERROR;
}

status_t VorbisPlayer::start()
{
    LOGV("start\n");
    Mutex::Autolock l(mMutex);
    if (mState != STATE_OPEN) {
        return ERROR_NOT_OPEN;
    }

    mPaused = false;
    mRender = true;

    // wake up render thread
    LOGV("  wakeup render thread\n");
    mCondition.signal();
    return NO_ERROR;
}

status_t VorbisPlayer::stop()
{
    LOGV("stop\n");
    Mutex::Autolock l(mMutex);
    if (mState != STATE_OPEN) {
        return ERROR_NOT_OPEN;
    }
    mPaused = true;
    mRender = false;
    return NO_ERROR;
}

status_t VorbisPlayer::seekTo(int position)
{
    LOGV("seekTo %d\n", position);
    Mutex::Autolock l(mMutex);
    if (mState != STATE_OPEN) {
        return ERROR_NOT_OPEN;
    }

    int result = ov_time_seek(&mVorbisFile, position);
    if (result != 0) {
        LOGE("ov_time_seek() returned %d\n", result);
        return result;
    }
    sendEvent(MEDIA_SEEK_COMPLETE);
    return NO_ERROR;
}

status_t VorbisPlayer::pause()
{
    LOGV("pause\n");
    Mutex::Autolock l(mMutex);
    if (mState != STATE_OPEN) {
        return ERROR_NOT_OPEN;
    }
    mPaused = true;
    return NO_ERROR;
}

bool VorbisPlayer::isPlaying()
{
    LOGV("isPlaying\n");
    if (mState == STATE_OPEN) {
        return mRender;
    }
    return false;
}

status_t VorbisPlayer::getCurrentPosition(int* position)
{
    LOGV("getCurrentPosition\n");
    Mutex::Autolock l(mMutex);
    if (mState != STATE_OPEN) {
        LOGE("getCurrentPosition(): file not open");
        return ERROR_NOT_OPEN;
    }
    *position = ov_time_tell(&mVorbisFile);
    if (*position < 0) {
        LOGE("getCurrentPosition(): ov_time_tell returned %d", *position);
        return *position;
    }
    return NO_ERROR;
}

status_t VorbisPlayer::getDuration(int* duration)
{
    LOGV("getDuration\n");
    Mutex::Autolock l(mMutex);
    if (mState != STATE_OPEN) {
        return ERROR_NOT_OPEN;
    }

    int ret = ov_time_total(&mVorbisFile, -1);
    if (ret == OV_EINVAL) {
        return -1;
    }

    *duration = ret;
    return NO_ERROR;
}

status_t VorbisPlayer::release()
{
    LOGV("release\n");
    Mutex::Autolock l(mMutex);
    reset_nosync();

    // TODO: timeout when thread won't exit
    // wait for render thread to exit
    if (mRenderTid > 0) {
        mExit = true;
        mCondition.signal();
        mCondition.wait(mMutex);
    }
    return NO_ERROR;
}

status_t VorbisPlayer::reset()
{
    LOGV("reset\n");
    Mutex::Autolock l(mMutex);
    return reset_nosync();
}

// always call with lock held
status_t VorbisPlayer::reset_nosync()
{
    // close file
    if (mFile != NULL) {
        ov_clear(&mVorbisFile); // this also closes the FILE
        if (mFile != NULL) {
            LOGV("OOPS! Vorbis didn't close the file");
            fclose(mFile);
            mFile = NULL;
        }
    }
    mState = STATE_ERROR;

    mPlayTime = -1;
    mDuration = -1;
    mLoop = false;
    mAndroidLoop = false;
    mPaused = false;
    mRender = false;
    return NO_ERROR;
}

status_t VorbisPlayer::setLooping(int loop)
{
    LOGV("setLooping\n");
    Mutex::Autolock l(mMutex);
    mLoop = (loop != 0);
    return NO_ERROR;
}

status_t VorbisPlayer::createOutputTrack() {
    // open audio track
    vorbis_info *vi = ov_info(&mVorbisFile, -1);

    LOGV("Create AudioTrack object: rate=%ld, channels=%d\n",
            vi->rate, vi->channels);
    if (mAudioSink->open(vi->rate, vi->channels, AudioSystem::PCM_16_BIT, DEFAULT_AUDIOSINK_BUFFERCOUNT) != NO_ERROR) {
        LOGE("mAudioSink open failed");
        return ERROR_OPEN_FAILED;
    }
    return NO_ERROR;
}

int VorbisPlayer::renderThread(void* p) {
    return ((VorbisPlayer*)p)->render();
}

#define AUDIOBUFFER_SIZE 4096

int VorbisPlayer::render() {
    int result = -1;
    int temp;
    int current_section = 0;
    bool audioStarted = false;

    LOGV("render\n");

    // allocate render buffer
    mAudioBuffer = new char[AUDIOBUFFER_SIZE];
    if (!mAudioBuffer) {
        LOGE("mAudioBuffer allocate failed\n");
        goto threadExit;
    }

    // let main thread know we're ready
    {
        Mutex::Autolock l(mMutex);
        mRenderTid = myTid();
        mCondition.signal();
    }

    while (1) {
        long numread = 0;
        {
            Mutex::Autolock l(mMutex);

            // pausing?
            if (mPaused) {
                if (mAudioSink->ready()) mAudioSink->pause();
                mRender = false;
                audioStarted = false;
            }

            // nothing to render, wait for client thread to wake us up
            if (!mExit && !mRender) {
                LOGV("render - signal wait\n");
                mCondition.wait(mMutex);
                LOGV("render - signal rx'd\n");
            }
            if (mExit) break;

            // We could end up here if start() is called, and before we get a
            // chance to run, the app calls stop() or reset(). Re-check render
            // flag so we don't try to render in stop or reset state.
            if (!mRender) continue;

            // render vorbis data into the input buffer
            numread = ov_read(&mVorbisFile, mAudioBuffer, AUDIOBUFFER_SIZE, &current_section);
            if (numread == 0) {
                // end of file, do we need to loop?
                // ...
                if (mLoop || mAndroidLoop) {
                    ov_time_seek(&mVorbisFile, 0);
                    current_section = 0;
                    numread = ov_read(&mVorbisFile, mAudioBuffer, AUDIOBUFFER_SIZE, &current_section);
                } else {
                    mAudioSink->stop();
                    audioStarted = false;
                    mRender = false;
                    mPaused = true;
                    int endpos = ov_time_tell(&mVorbisFile);

                    LOGV("send MEDIA_PLAYBACK_COMPLETE");
                    sendEvent(MEDIA_PLAYBACK_COMPLETE);

                    // wait until we're started again
                    LOGV("playback complete - wait for signal");
                    mCondition.wait(mMutex);
                    LOGV("playback complete - signal rx'd");
                    if (mExit) break;

                    // if we're still at the end, restart from the beginning
                    if (mState == STATE_OPEN) {
                        int curpos = ov_time_tell(&mVorbisFile);
                        if (curpos == endpos) {
                            ov_time_seek(&mVorbisFile, 0);
                        }
                        current_section = 0;
                        numread = ov_read(&mVorbisFile, mAudioBuffer, AUDIOBUFFER_SIZE, &current_section);
                    }
                }
            }
        }

        // codec returns negative number on error
        if (numread < 0) {
            LOGE("Error in Vorbis decoder");
            sendEvent(MEDIA_ERROR);
            break;
        }

        // create audio output track if necessary
        if (!mAudioSink->ready()) {
            LOGV("render - create output track\n");
            if (createOutputTrack() != NO_ERROR)
                break;
        }

        // Write data to the audio hardware
        if ((temp = mAudioSink->write(mAudioBuffer, numread)) < 0) {
            LOGE("Error in writing:%d",temp);
            result = temp;
            break;
        }

        // start audio output if necessary
        if (!audioStarted && !mPaused && !mExit) {
            LOGV("render - starting audio\n");
            mAudioSink->start();
            audioStarted = true;
        }
    }

threadExit:
    mAudioSink.clear();
    if (mAudioBuffer) {
        delete [] mAudioBuffer;
        mAudioBuffer = NULL;
    }

    // tell main thread goodbye
    Mutex::Autolock l(mMutex);
    mRenderTid = -1;
    mCondition.signal();
    return result;
}

} // end namespace android
