/*
 * 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 <binder/IBinder.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 <mediaplayer2/JavaVMHelper.h>
#include <mediaplayer2/JMedia2HTTPService.h>

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

#include <mutex> // std::call_once,once_flag
#include <dlfcn.h> // dlopen

using namespace android;

// load libandroid_runtime.so lazily.
// A vendor process may use libmediandk but should not depend on libandroid_runtime.
// TODO(jooyung): remove duplicate (b/125550121)
// frameworks/native/libs/binder/ndk/ibinder_jni.cpp
namespace {

typedef JNIEnv* (*getJNIEnv_t)();
typedef sp<IBinder> (*ibinderForJavaObject_t)(JNIEnv* env, jobject obj);

getJNIEnv_t getJNIEnv_;
ibinderForJavaObject_t ibinderForJavaObject_;

std::once_flag mLoadFlag;

void load() {
    std::call_once(mLoadFlag, []() {
        void* handle = dlopen("libandroid_runtime.so", RTLD_LAZY);
        if (handle == nullptr) {
            ALOGE("Could not open libandroid_runtime.");
            return;
        }

        getJNIEnv_ = reinterpret_cast<getJNIEnv_t>(
                dlsym(handle, "_ZN7android14AndroidRuntime9getJNIEnvEv"));
        if (getJNIEnv_ == nullptr) {
            ALOGE("Could not find AndroidRuntime::getJNIEnv.");
            // no return
        }

        ibinderForJavaObject_ = reinterpret_cast<ibinderForJavaObject_t>(
                dlsym(handle, "_ZN7android20ibinderForJavaObjectEP7_JNIEnvP8_jobject"));
        if (ibinderForJavaObject_ == nullptr) {
            ALOGE("Could not find ibinderForJavaObject.");
            // no return
        }
    });
}

JNIEnv* getJNIEnv() {
    load();
    if (getJNIEnv_ == nullptr) {
        return nullptr;
    }
    return (getJNIEnv_)();
}

sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) {
    load();
    if (ibinderForJavaObject_ == nullptr) {
        return nullptr;
    }
    return (ibinderForJavaObject_)(env, obj);
}

} // namespace

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, int version) {
    if (obj == NULL) {
        return NULL;
    }
    sp<IBinder> binder;
    switch (version) {
        case 1:
            binder = ibinderForJavaObject(env, obj);
            if (binder == NULL) {
                return NULL;
            }
            return interface_cast<IMediaHTTPService>(binder);
        case 2:
            return new JMedia2HTTPService(env, obj);
        default:
            return NULL;
    }
}

static sp<MediaHTTPService> createMediaHttpServiceTemplate(
        JNIEnv *env,
        const char *uri,
        const char *clazz,
        const char *method,
        const char *signature,
        int version) {
    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, version);
    return httpService;

}

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

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

    switch (version) {
        case 1:
            env = getJNIEnv();
            clazz = "android/media/MediaHTTPService";
            method = "createHttpServiceBinderIfNecessary";
            signature = "(Ljava/lang/String;)Landroid/os/IBinder;";
            break;
        case 2:
            env = JavaVMHelper::getJNIEnv();
            clazz = "android/media/Media2HTTPService";
            method = "createHTTPService";
            signature = "(Ljava/lang/String;)Landroid/media/Media2HTTPService;";
            break;
        default:
            return NULL;
    }

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

}

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, /* version = */ 1);
    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"

