/*
 * 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 "NdkJavaVMHelperPriv.h"
#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 <datasource/DataSourceFactory.h>
#include <datasource/HTTPBase.h>
#include <datasource/NuCachedSource2.h>
#include <media/IMediaHTTPService.h>
#include <media/NdkMediaError.h>
#include <media/NdkMediaDataSource.h>
#include <media/stagefright/InterfaceUtils.h>
#include <utils/Log.h>
#include <utils/StrongPointer.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 = NdkJavaVMHelper::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::getInstance()->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"

