/*
 * Copyright (C) 2016 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_TAG "EphemeralStorage"
//#define LOG_NDEBUG 0

#include <android-base/logging.h>

#include "EphemeralStorage.h"

using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;

namespace android {

EphemeralStorage::EphemeralStorage() {
}

EphemeralStorage::~EphemeralStorage() {
    CHECK(mItems.empty())
        << "All item storage should have been released by now.";
}

hidl_string *EphemeralStorage::allocStringArray(size_t size) {
    Item item;
    item.mType = TYPE_STRING_ARRAY;
    item.mObj = NULL;
    item.mPtr = new hidl_string[size];
    mItems.push_back(item);

    return static_cast<hidl_string *>(item.mPtr);
}

void *EphemeralStorage::allocTemporaryStorage(size_t size) {
    Item item;
    item.mType = TYPE_STORAGE;
    item.mObj = NULL;
    item.mPtr = malloc(size);
    mItems.push_back(item);

    return item.mPtr;
}

const hidl_string *EphemeralStorage::allocTemporaryString(
        JNIEnv *env, jstring stringObj) {
    jstring obj = (jstring)env->NewGlobalRef(stringObj);
    const char *val = env->GetStringUTFChars(obj, NULL);

    Item item;
    item.mType = TYPE_STRING;
    item.mObj = obj;
    item.mPtr = (void *)val;
    mItems.push_back(item);

    hidl_string *s = allocStringArray(1 /* size */);
    s->setToExternal((char *)val, strlen(val));

    return s;
}

#define DEFINE_ALLOC_VECTOR_METHODS(Suffix,Type,NewType)                       \
const hidl_vec<Type> *EphemeralStorage::allocTemporary ## Suffix ## Vector(    \
        JNIEnv *env, Type ## Array arrayObj) {                                 \
    Type ## Array obj = (Type ## Array)env->NewGlobalRef(arrayObj);            \
    jsize len = env->GetArrayLength(obj);                                      \
    const Type *val = env->Get ## NewType ## ArrayElements(obj, NULL);         \
                                                                               \
    Item item;                                                                 \
    item.mType = TYPE_ ## Suffix ## _ARRAY;                                    \
    item.mObj = obj;                                                           \
    item.mPtr = (void *)val;                                                   \
    mItems.push_back(item);                                                    \
                                                                               \
    void *vecPtr = allocTemporaryStorage(sizeof(hidl_vec<Type>));              \
                                                                               \
    hidl_vec<Type> *vec = new (vecPtr) hidl_vec<Type>;                         \
    vec->setToExternal(const_cast<Type *>(val), len);                          \
                                                                               \
    return vec;                                                                \
}

DEFINE_ALLOC_VECTOR_METHODS(Int8,jbyte,Byte)
DEFINE_ALLOC_VECTOR_METHODS(Int16,jshort,Short)
DEFINE_ALLOC_VECTOR_METHODS(Int32,jint,Int)
DEFINE_ALLOC_VECTOR_METHODS(Int64,jlong,Long)
DEFINE_ALLOC_VECTOR_METHODS(Float,jfloat,Float)
DEFINE_ALLOC_VECTOR_METHODS(Double,jdouble,Double)

#define DEFINE_RELEASE_ARRAY_CASE(Suffix,Type,NewType)                         \
            case TYPE_ ## Suffix ## _ARRAY:                                    \
            {                                                                  \
                env->Release ## NewType ## ArrayElements(                      \
                        (Type ## Array)item.mObj,                              \
                        (Type *)item.mPtr,                                     \
                        0 /* mode */);                                         \
                                                                               \
                env->DeleteGlobalRef(item.mObj);                               \
                break;                                                         \
            }

void EphemeralStorage::release(JNIEnv *env) {
    for (size_t i = mItems.size(); i--;) {
        const Item &item = mItems[i];

        switch (item.mType) {
            case TYPE_STRING_ARRAY:
            {
                delete[] static_cast<hidl_string *>(item.mPtr);
                break;
            }

            case TYPE_STORAGE:
            {
                free(item.mPtr);
                break;
            }

            case TYPE_STRING:
            {
                env->ReleaseStringUTFChars(
                        (jstring)item.mObj, (const char *)item.mPtr);

                env->DeleteGlobalRef(item.mObj);
                break;
            }

            DEFINE_RELEASE_ARRAY_CASE(Int8,jbyte,Byte)
            DEFINE_RELEASE_ARRAY_CASE(Int16,jshort,Short)
            DEFINE_RELEASE_ARRAY_CASE(Int32,jint,Int)
            DEFINE_RELEASE_ARRAY_CASE(Int64,jlong,Long)
            DEFINE_RELEASE_ARRAY_CASE(Float,jfloat,Float)
            DEFINE_RELEASE_ARRAY_CASE(Double,jdouble,Double)

            default:
                CHECK(!"Should not be here");
        }
    }

    mItems.clear();
}

}  // namespace android

