/*
 * Copyright (C) 2014 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 "MidiExtractor"
#include <utils/Log.h>

#include "MidiExtractor.h"

#include <media/MidiIoWrapper.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MetaData.h>
#include <media/MediaTrack.h>
#include <libsonivox/eas_reverb.h>

namespace android {

// how many Sonivox output buffers to aggregate into one MediaBufferBase
static const int NUM_COMBINE_BUFFERS = 4;

class MidiSource : public MediaTrack {

public:
    MidiSource(
            MidiEngine &engine,
            MetaDataBase &trackMetadata);

    virtual status_t start(MetaDataBase *params);
    virtual status_t stop();
    virtual status_t getFormat(MetaDataBase&);

    virtual status_t read(
            MediaBufferBase **buffer, const ReadOptions *options = NULL);

protected:
    virtual ~MidiSource();

private:
    MidiEngine &mEngine;
    MetaDataBase &mTrackMetadata;
    bool mInitCheck;
    bool mStarted;

    status_t init();

    // no copy constructor or assignment
    MidiSource(const MidiSource &);
    MidiSource &operator=(const MidiSource &);

};


// Midisource

MidiSource::MidiSource(
        MidiEngine &engine,
        MetaDataBase &trackMetadata)
    : mEngine(engine),
      mTrackMetadata(trackMetadata),
      mInitCheck(false),
      mStarted(false)
{
    ALOGV("MidiSource ctor");
    mInitCheck = init();
}

MidiSource::~MidiSource()
{
    ALOGV("MidiSource dtor");
    if (mStarted) {
        stop();
    }
}

status_t MidiSource::start(MetaDataBase * /* params */)
{
    ALOGV("MidiSource::start");

    CHECK(!mStarted);
    mStarted = true;
    mEngine.allocateBuffers();
    return OK;
}

status_t MidiSource::stop()
{
    ALOGV("MidiSource::stop");

    CHECK(mStarted);
    mStarted = false;
    mEngine.releaseBuffers();

    return OK;
}

status_t MidiSource::getFormat(MetaDataBase &meta)
{
    meta = mTrackMetadata;
    return OK;
}

status_t MidiSource::read(
        MediaBufferBase **outBuffer, const ReadOptions *options)
{
    ALOGV("MidiSource::read");
    MediaBufferBase *buffer;
    // process an optional seek request
    int64_t seekTimeUs;
    ReadOptions::SeekMode mode;
    if ((NULL != options) && options->getSeekTo(&seekTimeUs, &mode)) {
        if (seekTimeUs <= 0LL) {
            seekTimeUs = 0LL;
        }
        mEngine.seekTo(seekTimeUs);
    }
    buffer = mEngine.readBuffer();
    *outBuffer = buffer;
    ALOGV("MidiSource::read %p done", this);
    return buffer != NULL ? (status_t) OK : (status_t) ERROR_END_OF_STREAM;
}

status_t MidiSource::init()
{
    ALOGV("MidiSource::init");
    return OK;
}

// MidiEngine

MidiEngine::MidiEngine(DataSourceBase *dataSource,
        MetaDataBase *fileMetadata,
        MetaDataBase *trackMetadata) :
            mGroup(NULL),
            mEasData(NULL),
            mEasHandle(NULL),
            mEasConfig(NULL),
            mIsInitialized(false) {
    mIoWrapper = new MidiIoWrapper(dataSource);
    // spin up a new EAS engine
    EAS_I32 temp;
    EAS_RESULT result = EAS_Init(&mEasData);

    if (result == EAS_SUCCESS) {
        result = EAS_OpenFile(mEasData, mIoWrapper->getLocator(), &mEasHandle);
    }
    if (result == EAS_SUCCESS) {
        result = EAS_Prepare(mEasData, mEasHandle);
    }
    if (result == EAS_SUCCESS) {
        result = EAS_ParseMetaData(mEasData, mEasHandle, &temp);
    }

    if (result != EAS_SUCCESS) {
        return;
    }

    if (fileMetadata != NULL) {
        fileMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MIDI);
    }

    if (trackMetadata != NULL) {
        trackMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
        trackMetadata->setInt64(kKeyDuration, 1000ll * temp); // milli->micro
        mEasConfig = EAS_Config();
        trackMetadata->setInt32(kKeySampleRate, mEasConfig->sampleRate);
        trackMetadata->setInt32(kKeyChannelCount, mEasConfig->numChannels);
        trackMetadata->setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
    }
    mIsInitialized = true;
}

MidiEngine::~MidiEngine() {
    if (mEasHandle) {
        EAS_CloseFile(mEasData, mEasHandle);
    }
    if (mEasData) {
        EAS_Shutdown(mEasData);
    }
    delete mGroup;
    delete mIoWrapper;
}

status_t MidiEngine::initCheck() {
    return mIsInitialized ? OK : UNKNOWN_ERROR;
}

status_t MidiEngine::allocateBuffers() {
    // select reverb preset and enable
    EAS_SetParameter(mEasData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_PRESET, EAS_PARAM_REVERB_CHAMBER);
    EAS_SetParameter(mEasData, EAS_MODULE_REVERB, EAS_PARAM_REVERB_BYPASS, EAS_FALSE);

    mGroup = new MediaBufferGroup;
    int bufsize = sizeof(EAS_PCM)
            * mEasConfig->mixBufferSize * mEasConfig->numChannels * NUM_COMBINE_BUFFERS;
    ALOGV("using %d byte buffer", bufsize);
    mGroup->add_buffer(MediaBufferBase::Create(bufsize));
    return OK;
}

status_t MidiEngine::releaseBuffers() {
    delete mGroup;
    mGroup = NULL;
    return OK;
}

status_t MidiEngine::seekTo(int64_t positionUs) {
    ALOGV("seekTo %lld", (long long)positionUs);
    EAS_RESULT result = EAS_Locate(mEasData, mEasHandle, positionUs / 1000, false);
    return result == EAS_SUCCESS ? OK : UNKNOWN_ERROR;
}

MediaBufferBase* MidiEngine::readBuffer() {
    EAS_STATE state;
    EAS_State(mEasData, mEasHandle, &state);
    if ((state == EAS_STATE_STOPPED) || (state == EAS_STATE_ERROR)) {
        return NULL;
    }
    MediaBufferBase *buffer;
    status_t err = mGroup->acquire_buffer(&buffer);
    if (err != OK) {
        ALOGE("readBuffer: no buffer");
        return NULL;
    }
    EAS_I32 timeMs;
    EAS_GetLocation(mEasData, mEasHandle, &timeMs);
    int64_t timeUs = 1000ll * timeMs;
    buffer->meta_data().setInt64(kKeyTime, timeUs);

    EAS_PCM* p = (EAS_PCM*) buffer->data();
    int numBytesOutput = 0;
    for (int i = 0; i < NUM_COMBINE_BUFFERS; i++) {
        EAS_I32 numRendered;
        EAS_RESULT result = EAS_Render(mEasData, p, mEasConfig->mixBufferSize, &numRendered);
        if (result != EAS_SUCCESS) {
            ALOGE("EAS_Render() returned %ld, numBytesOutput = %d", result, numBytesOutput);
            buffer->release();
            return NULL; // Stop processing to prevent infinite loops.
        }
        p += numRendered * mEasConfig->numChannels;
        numBytesOutput += numRendered * mEasConfig->numChannels * sizeof(EAS_PCM);
    }
    buffer->set_range(0, numBytesOutput);
    ALOGV("readBuffer: returning %zd in buffer %p", buffer->range_length(), buffer);
    return buffer;
}


// MidiExtractor

MidiExtractor::MidiExtractor(
        DataSourceBase *dataSource)
    : mDataSource(dataSource),
      mInitCheck(false)
{
    ALOGV("MidiExtractor ctor");
    mEngine = new MidiEngine(mDataSource, &mFileMetadata, &mTrackMetadata);
    mInitCheck = mEngine->initCheck();
}

MidiExtractor::~MidiExtractor()
{
    ALOGV("MidiExtractor dtor");
}

size_t MidiExtractor::countTracks()
{
    return mInitCheck == OK ? 1 : 0;
}

MediaTrack *MidiExtractor::getTrack(size_t index)
{
    if (mInitCheck != OK || index > 0) {
        return NULL;
    }
    return new MidiSource(*mEngine, mTrackMetadata);
}

status_t MidiExtractor::getTrackMetaData(
        MetaDataBase &meta,
        size_t index, uint32_t /* flags */) {
    ALOGV("MidiExtractor::getTrackMetaData");
    if (mInitCheck != OK || index > 0) {
        return UNKNOWN_ERROR;
    }
    meta = mTrackMetadata;
    return OK;
}

status_t MidiExtractor::getMetaData(MetaDataBase &meta)
{
    ALOGV("MidiExtractor::getMetaData");
    meta = mFileMetadata;
    return OK;
}

// Sniffer

bool SniffMidi(DataSourceBase *source, float *confidence)
{
    MidiEngine p(source, NULL, NULL);
    if (p.initCheck() == OK) {
        *confidence = 0.8;
        ALOGV("SniffMidi: yes");
        return true;
    }
    ALOGV("SniffMidi: no");
    return false;

}

extern "C" {
// This is the only symbol that needs to be exported
__attribute__ ((visibility ("default")))
MediaExtractor::ExtractorDef GETEXTRACTORDEF() {
    return {
        MediaExtractor::EXTRACTORDEF_VERSION,
        UUID("ef6cca0a-f8a2-43e6-ba5f-dfcd7c9a7ef2"),
        1,
        "MIDI Extractor",
        [](
                DataSourceBase *source,
                float *confidence,
                void **,
                MediaExtractor::FreeMetaFunc *) -> MediaExtractor::CreatorFunc {
            if (SniffMidi(source, confidence)) {
                return [](
                        DataSourceBase *source,
                        void *) -> MediaExtractor* {
                    return new MidiExtractor(source);};
            }
            return NULL;
        }
    };
}

} // extern "C"

}  // namespace android
