/*
 * Copyright (C) 2018 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 "NdkMediaDataSource"

#include "NdkMediaDataSourcePriv.h"

#include <inttypes.h>
#include <jni.h>
#include <unistd.h>

#include <android_runtime/AndroidRuntime.h>
#include <android_util_Binder.h>
#include <cutils/properties.h>
#include <utils/Log.h>
#include <utils/StrongPointer.h>
#include <media/IMediaHTTPService.h>
#include <media/NdkMediaError.h>
#include <media/NdkMediaDataSource.h>
#include <media/stagefright/DataSourceFactory.h>
#include <media/stagefright/InterfaceUtils.h>

#include "../../libstagefright/include/HTTPBase.h"
#include "../../libstagefright/include/NuCachedSource2.h"
#include "NdkMediaDataSourceCallbacksPriv.h"


using namespace android;

struct AMediaDataSource {
    void *userdata;
    AMediaDataSourceReadAt readAt;
    AMediaDataSourceGetSize getSize;
    AMediaDataSourceClose close;
    AMediaDataSourceGetAvailableSize getAvailableSize;
    sp<DataSource> mImpl;
    uint32_t mFlags;
};

NdkDataSource::NdkDataSource(AMediaDataSource *dataSource)
    : mDataSource(AMediaDataSource_new()) {
    AMediaDataSource_setReadAt(mDataSource, dataSource->readAt);
    AMediaDataSource_setGetSize(mDataSource, dataSource->getSize);
    AMediaDataSource_setClose(mDataSource, dataSource->close);
    AMediaDataSource_setUserdata(mDataSource, dataSource->userdata);
    AMediaDataSource_setGetAvailableSize(mDataSource, dataSource->getAvailableSize);
    mDataSource->mImpl = dataSource->mImpl;
    mDataSource->mFlags = dataSource->mFlags;
}

NdkDataSource::~NdkDataSource() {
    AMediaDataSource_delete(mDataSource);
}

status_t NdkDataSource::initCheck() const {
    return OK;
}

uint32_t NdkDataSource::flags() {
    return mDataSource->mFlags;
}

ssize_t NdkDataSource::readAt(off64_t offset, void *data, size_t size) {
    Mutex::Autolock l(mLock);
    if (mDataSource->readAt == NULL || mDataSource->userdata == NULL) {
        return -1;
    }
    return mDataSource->readAt(mDataSource->userdata, offset, data, size);
}

status_t NdkDataSource::getSize(off64_t *size) {
    Mutex::Autolock l(mLock);
    if (mDataSource->getSize == NULL || mDataSource->userdata == NULL) {
        return NO_INIT;
    }
    if (size != NULL) {
        *size = mDataSource->getSize(mDataSource->userdata);
    }
    return OK;
}

String8 NdkDataSource::toString() {
    return String8::format("NdkDataSource(pid %d, uid %d)", getpid(), getuid());
}

String8 NdkDataSource::getMIMEType() const {
    return String8("application/octet-stream");
}

void NdkDataSource::close() {
    if (mDataSource->close != NULL && mDataSource->userdata != NULL) {
        mDataSource->close(mDataSource->userdata);
    }
}

status_t NdkDataSource::getAvailableSize(off64_t offset, off64_t *sizeptr) {
    off64_t size = -1;
    if (mDataSource->getAvailableSize != NULL
            && mDataSource->userdata != NULL
            && sizeptr != NULL) {
        size = mDataSource->getAvailableSize(mDataSource->userdata, offset);
        *sizeptr = size;
    }
    return size >= 0 ? OK : UNKNOWN_ERROR;
}

static sp<MediaHTTPService> createMediaHttpServiceFromJavaObj(JNIEnv *env, jobject obj) {
    if (obj == NULL) {
        return NULL;
    }
    return interface_cast<IMediaHTTPService>(ibinderForJavaObject(env, obj));
}

static sp<MediaHTTPService> createMediaHttpServiceTemplate(
        JNIEnv *env,
        const char *uri,
        const char *clazz,
        const char *method,
        const char *signature) {
    jobject service = NULL;
    if (env == NULL) {
        ALOGE("http service must be created from Java thread");
        return NULL;
    }

    jclass mediahttpclass = env->FindClass(clazz);
    if (mediahttpclass == NULL) {
        ALOGE("can't find Media(2)HttpService");
        env->ExceptionClear();
        return NULL;
    }

    jmethodID mediaHttpCreateMethod = env->GetStaticMethodID(mediahttpclass, method, signature);
    if (mediaHttpCreateMethod == NULL) {
        ALOGE("can't find method");
        env->ExceptionClear();
        return NULL;
    }

    jstring juri = env->NewStringUTF(uri);

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

    env->ExceptionClear();
    sp<MediaHTTPService> httpService = createMediaHttpServiceFromJavaObj(env, service);
    return httpService;

}

sp<MediaHTTPService> createMediaHttpService(const char *uri) {

    JNIEnv *env;
    const char *clazz, *method, *signature;

    env = AndroidRuntime::getJNIEnv();
    clazz = "android/media/MediaHTTPService";
    method = "createHttpServiceBinderIfNecessary";
    signature = "(Ljava/lang/String;)Landroid/os/IBinder;";

    return createMediaHttpServiceTemplate(env, uri, clazz, method, signature);

}

extern "C" {

EXPORT
AMediaDataSource* AMediaDataSource_new() {
    AMediaDataSource *mSource = new AMediaDataSource();
    mSource->userdata = NULL;
    mSource->readAt = NULL;
    mSource->getSize = NULL;
    mSource->close = NULL;
    return mSource;
}

EXPORT
AMediaDataSource* AMediaDataSource_newUri(
        const char *uri,
        int numheaders,
        const char * const *key_values) {

    sp<MediaHTTPService> service = createMediaHttpService(uri);
    KeyedVector<String8, String8> headers;
    for (int i = 0; i < numheaders; ++i) {
        String8 key8(key_values[i * 2]);
        String8 value8(key_values[i * 2 + 1]);
        headers.add(key8, value8);
    }

    sp<DataSource> source = DataSourceFactory::CreateFromURI(service, uri, &headers);
    if (source == NULL) {
        ALOGE("AMediaDataSource_newUri source is null");
        return NULL;
    }
    ALOGI("AMediaDataSource_newUri source %s flags %u", source->toString().c_str(), source->flags());
    AMediaDataSource* aSource = convertDataSourceToAMediaDataSource(source);
    aSource->mImpl = source;
    aSource->mFlags = source->flags();
    return aSource;
}

EXPORT
void AMediaDataSource_delete(AMediaDataSource *mSource) {
    ALOGV("dtor");
    if (mSource != NULL) {
        delete mSource;
    }
}

EXPORT
void AMediaDataSource_setUserdata(AMediaDataSource *mSource, void *userdata) {
    mSource->userdata = userdata;
}

EXPORT
void AMediaDataSource_setReadAt(AMediaDataSource *mSource, AMediaDataSourceReadAt readAt) {
    mSource->readAt = readAt;
}

EXPORT
void AMediaDataSource_setGetSize(AMediaDataSource *mSource, AMediaDataSourceGetSize getSize) {
    mSource->getSize = getSize;
}

EXPORT
void AMediaDataSource_setClose(AMediaDataSource *mSource, AMediaDataSourceClose close) {
    mSource->close = close;
}

EXPORT
void AMediaDataSource_close(AMediaDataSource *mSource) {
    return mSource->close(mSource->userdata);
}

EXPORT
void AMediaDataSource_setGetAvailableSize(AMediaDataSource *mSource,
        AMediaDataSourceGetAvailableSize getAvailableSize) {
    mSource->getAvailableSize = getAvailableSize;
}

} // extern "C"

