/*
 * 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 "NdkMediaExtractor"


#include "NdkMediaError.h"
#include "NdkMediaExtractor.h"
#include "NdkMediaFormatPriv.h"


#include <inttypes.h>
#include <utils/Log.h>
#include <utils/StrongPointer.h>
#include <media/hardware/CryptoAPI.h>
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MetaData.h>
#include <media/stagefright/NuMediaExtractor.h>
#include <media/IMediaHTTPService.h>
#include <android_runtime/AndroidRuntime.h>
#include <android_util_Binder.h>

#include <jni.h>

using namespace android;

static media_status_t translate_error(status_t err) {
    if (err == OK) {
        return AMEDIA_OK;
    }
    ALOGE("sf error code: %d", err);
    return AMEDIA_ERROR_UNKNOWN;
}

struct AMediaExtractor {
    sp<NuMediaExtractor> mImpl;
    sp<ABuffer> mPsshBuf;

};

extern "C" {

EXPORT
AMediaExtractor* AMediaExtractor_new() {
    ALOGV("ctor");
    AMediaExtractor *mData = new AMediaExtractor();
    mData->mImpl = new NuMediaExtractor();
    return mData;
}

EXPORT
media_status_t AMediaExtractor_delete(AMediaExtractor *mData) {
    ALOGV("dtor");
    delete mData;
    return AMEDIA_OK;
}

EXPORT
media_status_t AMediaExtractor_setDataSourceFd(AMediaExtractor *mData, int fd, off64_t offset,
        off64_t length) {
    ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length);
    return translate_error(mData->mImpl->setDataSource(fd, offset, length));
}

EXPORT
media_status_t AMediaExtractor_setDataSource(AMediaExtractor *mData, const char *location) {
    ALOGV("setDataSource(%s)", location);
    // TODO: add header support

    JNIEnv *env = AndroidRuntime::getJNIEnv();
    jobject service = NULL;
    if (env == NULL) {
        ALOGE("setDataSource(path) must be called from Java thread");
        return AMEDIA_ERROR_UNSUPPORTED;
    }

    jclass mediahttpclass = env->FindClass("android/media/MediaHTTPService");
    if (mediahttpclass == NULL) {
        ALOGE("can't find MediaHttpService");
        env->ExceptionClear();
        return AMEDIA_ERROR_UNSUPPORTED;
    }

    jmethodID mediaHttpCreateMethod = env->GetStaticMethodID(mediahttpclass,
            "createHttpServiceBinderIfNecessary", "(Ljava/lang/String;)Landroid/os/IBinder;");
    if (mediaHttpCreateMethod == NULL) {
        ALOGE("can't find method");
        env->ExceptionClear();
        return AMEDIA_ERROR_UNSUPPORTED;
    }

    jstring jloc = env->NewStringUTF(location);

    service = env->CallStaticObjectMethod(mediahttpclass, mediaHttpCreateMethod, jloc);
    env->DeleteLocalRef(jloc);

    sp<IMediaHTTPService> httpService;
    if (service != NULL) {
        sp<IBinder> binder = ibinderForJavaObject(env, service);
        httpService = interface_cast<IMediaHTTPService>(binder);
    }

    status_t err = mData->mImpl->setDataSource(httpService, location, NULL);
    env->ExceptionClear();
    return translate_error(err);
}

EXPORT
size_t AMediaExtractor_getTrackCount(AMediaExtractor *mData) {
    return mData->mImpl->countTracks();
}

EXPORT
AMediaFormat* AMediaExtractor_getTrackFormat(AMediaExtractor *mData, size_t idx) {
    sp<AMessage> format;
    mData->mImpl->getTrackFormat(idx, &format);
    return AMediaFormat_fromMsg(&format);
}

EXPORT
media_status_t AMediaExtractor_selectTrack(AMediaExtractor *mData, size_t idx) {
    ALOGV("selectTrack(%zu)", idx);
    return translate_error(mData->mImpl->selectTrack(idx));
}

EXPORT
media_status_t AMediaExtractor_unselectTrack(AMediaExtractor *mData, size_t idx) {
    ALOGV("unselectTrack(%zu)", idx);
    return translate_error(mData->mImpl->unselectTrack(idx));
}

EXPORT
bool AMediaExtractor_advance(AMediaExtractor *mData) {
    //ALOGV("advance");
    status_t err = mData->mImpl->advance();
    if (err == ERROR_END_OF_STREAM) {
        return false;
    } else if (err != OK) {
        ALOGE("sf error code: %d", err);
        return false;
    }
    return true;
}

EXPORT
media_status_t AMediaExtractor_seekTo(AMediaExtractor *ex, int64_t seekPosUs, SeekMode mode) {
    android::MediaSource::ReadOptions::SeekMode sfmode;
    if (mode == AMEDIAEXTRACTOR_SEEK_PREVIOUS_SYNC) {
        sfmode = android::MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC;
    } else if (mode == AMEDIAEXTRACTOR_SEEK_CLOSEST_SYNC) {
        sfmode = android::MediaSource::ReadOptions::SEEK_CLOSEST_SYNC;
    } else {
        sfmode = android::MediaSource::ReadOptions::SEEK_NEXT_SYNC;
    }

    return translate_error(ex->mImpl->seekTo(seekPosUs, sfmode));
}

EXPORT
ssize_t AMediaExtractor_readSampleData(AMediaExtractor *mData, uint8_t *buffer, size_t capacity) {
    //ALOGV("readSampleData");
    sp<ABuffer> tmp = new ABuffer(buffer, capacity);
    if (mData->mImpl->readSampleData(tmp) == OK) {
        return tmp->size();
    }
    return -1;
}

EXPORT
uint32_t AMediaExtractor_getSampleFlags(AMediaExtractor *mData) {
    int sampleFlags = 0;
    sp<MetaData> meta;
    status_t err = mData->mImpl->getSampleMeta(&meta);
    if (err != OK) {
        return -1;
    }
    int32_t val;
    if (meta->findInt32(kKeyIsSyncFrame, &val) && val != 0) {
        sampleFlags |= AMEDIAEXTRACTOR_SAMPLE_FLAG_SYNC;
    }

    uint32_t type;
    const void *data;
    size_t size;
    if (meta->findData(kKeyEncryptedSizes, &type, &data, &size)) {
        sampleFlags |= AMEDIAEXTRACTOR_SAMPLE_FLAG_ENCRYPTED;
    }
    return sampleFlags;
}

EXPORT
int AMediaExtractor_getSampleTrackIndex(AMediaExtractor *mData) {
    size_t idx;
    if (mData->mImpl->getSampleTrackIndex(&idx) != OK) {
        return -1;
    }
    return idx;
}

EXPORT
int64_t AMediaExtractor_getSampleTime(AMediaExtractor *mData) {
    int64_t time;
    if (mData->mImpl->getSampleTime(&time) != OK) {
        return -1;
    }
    return time;
}

EXPORT
PsshInfo* AMediaExtractor_getPsshInfo(AMediaExtractor *ex) {

    if (ex->mPsshBuf != NULL) {
        return (PsshInfo*) ex->mPsshBuf->data();
    }

    sp<AMessage> format;
    ex->mImpl->getFileFormat(&format);
    sp<ABuffer> buffer;
    if(!format->findBuffer("pssh", &buffer)) {
        return NULL;
    }

    // the format of the buffer is 1 or more of:
    //    {
    //        16 byte uuid
    //        4 byte data length N
    //        N bytes of data
    //    }

    // Determine the number of entries in the source data.
    // Since we got the data from stagefright, we trust it is valid and properly formatted.
    const uint8_t* data = buffer->data();
    size_t len = buffer->size();
    size_t numentries = 0;
    while (len > 0) {
        numentries++;

        if (len < 16) {
            ALOGE("invalid PSSH data");
            return NULL;
        }
        // skip uuid
        data += 16;
        len -= 16;

        // get data length
        if (len < 4) {
            ALOGE("invalid PSSH data");
            return NULL;
        }
        uint32_t datalen = *((uint32_t*)data);
        data += 4;
        len -= 4;

        if (len < datalen) {
            ALOGE("invalid PSSH data");
            return NULL;
        }
        // skip the data
        data += datalen;
        len -= datalen;
    }

    // there are <numentries> in the source buffer, we need
    // (source buffer size) - (sizeof(uint32_t) * numentries) + sizeof(size_t)
    //  + ((sizeof(void*) + sizeof(size_t)) * numentries) bytes for the PsshInfo structure
    // Or in other words, the data lengths in the source structure are replaced by size_t
    // (which may be the same size or larger, for 64 bit), and in addition there is an
    // extra pointer for each entry, and an extra size_t for the entire PsshInfo.
    size_t newsize = buffer->size() - (sizeof(uint32_t) * numentries) + sizeof(size_t)
            + ((sizeof(void*) + sizeof(size_t)) * numentries);
    if (newsize <= buffer->size()) {
        ALOGE("invalid PSSH data");
        return NULL;
    }
    ex->mPsshBuf = new ABuffer(newsize);
    ex->mPsshBuf->setRange(0, newsize);

    // copy data
    const uint8_t* src = buffer->data();
    uint8_t* dst = ex->mPsshBuf->data();
    uint8_t* dstdata = dst + sizeof(size_t) + numentries * sizeof(PsshEntry);
    *((size_t*)dst) = numentries;
    dst += sizeof(size_t);
    for (size_t i = 0; i < numentries; i++) {
        // copy uuid
        memcpy(dst, src, 16);
        src += 16;
        dst += 16;

        // get/copy data length
        uint32_t datalen = *((uint32_t*)src);
        *((size_t*)dst) = datalen;
        src += sizeof(uint32_t);
        dst += sizeof(size_t);

        // the next entry in the destination is a pointer to the actual data, which we store
        // after the array of PsshEntry
        *((void**)dst) = dstdata;
        dst += sizeof(void*);

        // copy the actual data
        memcpy(dstdata, src, datalen);
        dstdata += datalen;
        src += datalen;
    }

    return (PsshInfo*) ex->mPsshBuf->data();
}

EXPORT
AMediaCodecCryptoInfo *AMediaExtractor_getSampleCryptoInfo(AMediaExtractor *ex) {
    sp<MetaData> meta;
    if(ex->mImpl->getSampleMeta(&meta) != 0) {
        return NULL;
    }

    uint32_t type;
    const void *crypteddata;
    size_t cryptedsize;
    if (!meta->findData(kKeyEncryptedSizes, &type, &crypteddata, &cryptedsize)) {
        return NULL;
    }
    size_t numSubSamples = cryptedsize / sizeof(size_t);

    const void *cleardata;
    size_t clearsize;
    if (meta->findData(kKeyPlainSizes, &type, &cleardata, &clearsize)) {
        if (clearsize != cryptedsize) {
            // The two must be of the same length.
            return NULL;
        }
    }

    const void *key;
    size_t keysize;
    if (meta->findData(kKeyCryptoKey, &type, &key, &keysize)) {
        if (keysize != 16) {
            // Keys must be 16 bytes in length.
            return NULL;
        }
    }

    const void *iv;
    size_t ivsize;
    if (meta->findData(kKeyCryptoIV, &type, &iv, &ivsize)) {
        if (ivsize != 16) {
            // IVs must be 16 bytes in length.
            return NULL;
        }
    }

    int32_t mode;
    if (!meta->findInt32(kKeyCryptoMode, &mode)) {
        mode = CryptoPlugin::kMode_AES_CTR;
    }

    return AMediaCodecCryptoInfo_new(
            numSubSamples,
            (uint8_t*) key,
            (uint8_t*) iv,
            (cryptoinfo_mode_t) mode,
            (size_t*) cleardata,
            (size_t*) crypteddata);
}


} // extern "C"

