/*
 * 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_TAG "MediaMetricsJNI"

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

#include "android_media_MediaMetricsJNI.h"
#include <media/MediaAnalyticsItem.h>


// This source file is compiled and linked into:
// core/jni/ (libandroid_runtime.so)

namespace android {

// place the attributes into a java PersistableBundle object
jobject MediaMetricsJNI::writeMetricsToBundle(JNIEnv* env, MediaAnalyticsItem *item, jobject mybundle) {

    jclass clazzBundle = env->FindClass("android/os/PersistableBundle");
    if (clazzBundle==NULL) {
        ALOGE("can't find android/os/PersistableBundle");
        return NULL;
    }
    // sometimes the caller provides one for us to fill
    if (mybundle == NULL) {
        // create the bundle
        jmethodID constructID = env->GetMethodID(clazzBundle, "<init>", "()V");
        mybundle = env->NewObject(clazzBundle, constructID);
        if (mybundle == NULL) {
            return NULL;
        }
    }

    // grab methods that we can invoke
    jmethodID setIntID = env->GetMethodID(clazzBundle, "putInt", "(Ljava/lang/String;I)V");
    jmethodID setLongID = env->GetMethodID(clazzBundle, "putLong", "(Ljava/lang/String;J)V");
    jmethodID setDoubleID = env->GetMethodID(clazzBundle, "putDouble", "(Ljava/lang/String;D)V");
    jmethodID setStringID = env->GetMethodID(clazzBundle, "putString", "(Ljava/lang/String;Ljava/lang/String;)V");

    // env, class, method, {parms}
    //env->CallVoidMethod(env, mybundle, setIntID, jstr, jint);

    // iterate through my attributes
    // -- get name, get type, get value
    // -- insert appropriately into the bundle
    for (size_t i = 0 ; i < item->mPropCount; i++ ) {
            MediaAnalyticsItem::Prop *prop = &item->mProps[i];
            // build the key parameter from prop->mName
            jstring keyName = env->NewStringUTF(prop->mName);
            // invoke the appropriate method to insert
            switch (prop->mType) {
                case MediaAnalyticsItem::kTypeInt32:
                    env->CallVoidMethod(mybundle, setIntID,
                                        keyName, (jint) prop->u.int32Value);
                    break;
                case MediaAnalyticsItem::kTypeInt64:
                    env->CallVoidMethod(mybundle, setLongID,
                                        keyName, (jlong) prop->u.int64Value);
                    break;
                case MediaAnalyticsItem::kTypeDouble:
                    env->CallVoidMethod(mybundle, setDoubleID,
                                        keyName, (jdouble) prop->u.doubleValue);
                    break;
                case MediaAnalyticsItem::kTypeCString:
                    env->CallVoidMethod(mybundle, setStringID, keyName,
                                        env->NewStringUTF(prop->u.CStringValue));
                    break;
                default:
                        ALOGE("to_String bad item type: %d for %s",
                              prop->mType, prop->mName);
                        break;
            }
    }

    return mybundle;
}

// convert the specified batch  metrics attributes to a persistent bundle.
// The encoding of the byte array is specified in
//     frameworks/av/media/libmediametrics/MediaAnalyticsItem.cpp
//
// type encodings; matches frameworks/av/media/libmediametrics/MediaAnalyticsItem.cpp
enum { kInt32 = 0, kInt64, kDouble, kRate, kCString};

jobject MediaMetricsJNI::writeAttributesToBundle(JNIEnv* env, jobject mybundle, char *buffer, size_t length) {
    ALOGV("writeAttributes()");

    if (buffer == NULL || length <= 0) {
        ALOGW("bad parameters to writeAttributesToBundle()");
        return NULL;
    }

    jclass clazzBundle = env->FindClass("android/os/PersistableBundle");
    if (clazzBundle==NULL) {
        ALOGE("can't find android/os/PersistableBundle");
        return NULL;
    }
    // sometimes the caller provides one for us to fill
    if (mybundle == NULL) {
        // create the bundle
        jmethodID constructID = env->GetMethodID(clazzBundle, "<init>", "()V");
        mybundle = env->NewObject(clazzBundle, constructID);
        if (mybundle == NULL) {
            ALOGD("unable to create mybundle");
            return NULL;
        }
    }

    int left = length;
    char *buf = buffer;

    // grab methods that we can invoke
    jmethodID setIntID = env->GetMethodID(clazzBundle, "putInt", "(Ljava/lang/String;I)V");
    jmethodID setLongID = env->GetMethodID(clazzBundle, "putLong", "(Ljava/lang/String;J)V");
    jmethodID setDoubleID = env->GetMethodID(clazzBundle, "putDouble", "(Ljava/lang/String;D)V");
    jmethodID setStringID = env->GetMethodID(clazzBundle, "putString", "(Ljava/lang/String;Ljava/lang/String;)V");


#define _EXTRACT(size, val) \
    { if ((size) > left) goto badness; memcpy(&val, buf, (size)); buf += (size); left -= (size);}
#define _SKIP(size) \
    { if ((size) > left) goto badness; buf += (size); left -= (size);}

    int32_t bufsize;
    _EXTRACT(sizeof(int32_t), bufsize);
    if (bufsize != length) {
        goto badness;
    }
    int32_t proto;
    _EXTRACT(sizeof(int32_t), proto);
    if (proto != 0) {
        ALOGE("unsupported wire protocol %d", proto);
        goto badness;
    }

    int32_t count;
    _EXTRACT(sizeof(int32_t), count);

    // iterate through my attributes
    // -- get name, get type, get value, insert into bundle appropriately.
    for (int i = 0 ; i < count; i++ ) {
            // prop name len (int16)
            int16_t keylen;
            _EXTRACT(sizeof(int16_t), keylen);
            if (keylen <= 0) goto badness;
            // prop name itself
            char *key = buf;
            jstring keyName = env->NewStringUTF(buf);
            _SKIP(keylen);

            // prop type (int8_t)
            int8_t attrType;
            _EXTRACT(sizeof(int8_t), attrType);

	    int16_t attrSize;
            _EXTRACT(sizeof(int16_t), attrSize);

            switch (attrType) {
                case kInt32:
                    {
                        int32_t i32;
                        _EXTRACT(sizeof(int32_t), i32);
                        env->CallVoidMethod(mybundle, setIntID,
                                            keyName, (jint) i32);
                        break;
                    }
                case kInt64:
                    {
                        int64_t i64;
                        _EXTRACT(sizeof(int64_t), i64);
                        env->CallVoidMethod(mybundle, setLongID,
                                            keyName, (jlong) i64);
                        break;
                    }
                case kDouble:
                    {
                        double d64;
                        _EXTRACT(sizeof(double), d64);
                        env->CallVoidMethod(mybundle, setDoubleID,
                                            keyName, (jdouble) d64);
                        break;
                    }
                case kCString:
                    {
                        jstring value = env->NewStringUTF(buf);
                        env->CallVoidMethod(mybundle, setStringID,
                                            keyName, value);
                        _SKIP(attrSize);
                        break;
                    }
                default:
                        ALOGW("ignoring Attribute '%s' unknown type: %d",
                              key, attrType);
			_SKIP(attrSize);
                        break;
            }
    }

    // should have consumed it all
    if (left != 0) {
        ALOGW("did not consume entire buffer; left(%d) != 0", left);
	goto badness;
    }

    return mybundle;

  badness:
    return NULL;
}

};  // namespace android

