/*
 * Copyright 2017, 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 "JMedia2HTTPConnection"
#include <utils/Log.h>

#include <mediaplayer2/JavaVMHelper.h>
#include <mediaplayer2/JMedia2HTTPConnection.h>
#include <media/stagefright/foundation/ADebug.h>
#include <nativehelper/ScopedLocalRef.h>

#include "log/log.h"
#include "jni.h"
#include <nativehelper/JNIHelp.h>

namespace android {

static const size_t kBufferSize = 32768;

JMedia2HTTPConnection::JMedia2HTTPConnection(JNIEnv *env, jobject thiz) {
    mMedia2HTTPConnectionObj = env->NewGlobalRef(thiz);
    CHECK(mMedia2HTTPConnectionObj != NULL);

    ScopedLocalRef<jclass> media2HTTPConnectionClass(
            env, env->GetObjectClass(mMedia2HTTPConnectionObj));
    CHECK(media2HTTPConnectionClass.get() != NULL);

    mConnectMethod = env->GetMethodID(
            media2HTTPConnectionClass.get(),
            "connect",
            "(Ljava/lang/String;Ljava/lang/String;)Z");
    CHECK(mConnectMethod != NULL);

    mDisconnectMethod = env->GetMethodID(
            media2HTTPConnectionClass.get(),
            "disconnect",
            "()V");
    CHECK(mDisconnectMethod != NULL);

    mReadAtMethod = env->GetMethodID(
            media2HTTPConnectionClass.get(),
            "readAt",
            "(J[BI)I");
    CHECK(mReadAtMethod != NULL);

    mGetSizeMethod = env->GetMethodID(
            media2HTTPConnectionClass.get(),
            "getSize",
            "()J");
    CHECK(mGetSizeMethod != NULL);

    mGetMIMETypeMethod = env->GetMethodID(
            media2HTTPConnectionClass.get(),
            "getMIMEType",
            "()Ljava/lang/String;");
    CHECK(mGetMIMETypeMethod != NULL);

    mGetUriMethod = env->GetMethodID(
            media2HTTPConnectionClass.get(),
            "getUri",
            "()Ljava/lang/String;");
    CHECK(mGetUriMethod != NULL);

    ScopedLocalRef<jbyteArray> tmp(
        env, env->NewByteArray(kBufferSize));
    mByteArrayObj = (jbyteArray)env->NewGlobalRef(tmp.get());
    CHECK(mByteArrayObj != NULL);
}

JMedia2HTTPConnection::~JMedia2HTTPConnection() {
    JNIEnv *env = JavaVMHelper::getJNIEnv();
    env->DeleteGlobalRef(mMedia2HTTPConnectionObj);
    env->DeleteGlobalRef(mByteArrayObj);
}

bool JMedia2HTTPConnection::connect(
        const char *uri, const KeyedVector<String8, String8> *headers) {
    String8 tmp("");
    if (headers != NULL) {
        for (size_t i = 0; i < headers->size(); ++i) {
            tmp.append(headers->keyAt(i));
            tmp.append(String8(": "));
            tmp.append(headers->valueAt(i));
            tmp.append(String8("\r\n"));
        }
    }

    JNIEnv* env = JavaVMHelper::getJNIEnv();
    jstring juri = env->NewStringUTF(uri);
    jstring jheaders = env->NewStringUTF(tmp.string());

    jboolean ret =
        env->CallBooleanMethod(mMedia2HTTPConnectionObj, mConnectMethod, juri, jheaders);

    env->DeleteLocalRef(juri);
    env->DeleteLocalRef(jheaders);

    return (bool)ret;
}

void JMedia2HTTPConnection::disconnect() {
    JNIEnv* env = JavaVMHelper::getJNIEnv();
    env->CallVoidMethod(mMedia2HTTPConnectionObj, mDisconnectMethod);
}

ssize_t JMedia2HTTPConnection::readAt(off64_t offset, void *data, size_t size) {
    JNIEnv* env = JavaVMHelper::getJNIEnv();

    if (size > kBufferSize) {
        size = kBufferSize;
    }

    jint n = env->CallIntMethod(
            mMedia2HTTPConnectionObj, mReadAtMethod, (jlong)offset, mByteArrayObj, (jint)size);

    if (n > 0) {
        env->GetByteArrayRegion(
                mByteArrayObj,
                0,
                n,
                (jbyte *)data);
    }

    return n;
}

off64_t JMedia2HTTPConnection::getSize() {
    JNIEnv* env = JavaVMHelper::getJNIEnv();
    return (off64_t)(env->CallLongMethod(mMedia2HTTPConnectionObj, mGetSizeMethod));
}

status_t JMedia2HTTPConnection::getMIMEType(String8 *mimeType) {
    JNIEnv* env = JavaVMHelper::getJNIEnv();
    jstring jmime = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetMIMETypeMethod);
    jboolean flag = env->ExceptionCheck();
    if (flag) {
        env->ExceptionClear();
        return UNKNOWN_ERROR;
    }

    const char *str = env->GetStringUTFChars(jmime, 0);
    if (str != NULL) {
        *mimeType = String8(str);
    } else {
        *mimeType = "application/octet-stream";
    }
    env->ReleaseStringUTFChars(jmime, str);
    return OK;
}

status_t JMedia2HTTPConnection::getUri(String8 *uri) {
    JNIEnv* env = JavaVMHelper::getJNIEnv();
    jstring juri = (jstring)env->CallObjectMethod(mMedia2HTTPConnectionObj, mGetUriMethod);
    jboolean flag = env->ExceptionCheck();
    if (flag) {
        env->ExceptionClear();
        return UNKNOWN_ERROR;
    }

    const char *str = env->GetStringUTFChars(juri, 0);
    *uri = String8(str);
    env->ReleaseStringUTFChars(juri, str);
    return OK;
}

}  // namespace android
