/*
** 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 *uri, const KeyedVector<String8, String8> *headers) {
    return setdatasource(uri, -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
