/*
 * 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 "AudioProductStrategies-JNI"

#include <inttypes.h>
#include <jni.h>
#include <nativehelper/JNIHelp.h>
#include "core_jni_helpers.h"

#include <utils/Log.h>
#include <vector>

#include <media/AudioSystem.h>
#include <media/AudioPolicy.h>

#include <nativehelper/ScopedUtfChars.h>

#include "android_media_AudioAttributes.h"
#include "android_media_AudioErrors.h"

// ----------------------------------------------------------------------------

using namespace android;

// ----------------------------------------------------------------------------
static const char* const kClassPathName = "android/media/audiopolicy/AudioProductStrategies";
static const char* const kAudioProductStrategyClassPathName =
        "android/media/audiopolicy/AudioProductStrategy";

static const char* const kAudioAttributesGroupsClassPathName =
        "android/media/audiopolicy/AudioProductStrategy$AudioAttributesGroup";

static jclass gAudioProductStrategyClass;
static jmethodID gAudioProductStrategyCstor;
static struct {
    jfieldID    mAudioAttributesGroups;
    jfieldID    mName;
    jfieldID    mId;
} gAudioProductStrategyFields;

static jclass gAudioAttributesGroupClass;
static jmethodID gAudioAttributesGroupCstor;
static struct {
    jfieldID    mVolumeGroupId;
    jfieldID    mLegacyStreamType;
    jfieldID    mAudioAttributes;
} gAudioAttributesGroupsFields;

static jclass gArrayListClass;
static struct {
    jmethodID    add;
    jmethodID    toArray;
} gArrayListMethods;


static jint convertAudioProductStrategiesFromNative(
        JNIEnv *env, jobject *jAudioStrategy, const AudioProductStrategy &strategy)
{
    jint jStatus = (jint)AUDIO_JAVA_SUCCESS;
    jobjectArray jAudioAttributesGroups = NULL;
    jobjectArray jAudioAttributes = NULL;
    jobject jAudioAttribute = NULL;
    jstring jName = NULL;
    jint jStrategyId = NULL;
    jint numAttributesGroups;
    size_t indexGroup = 0;

    jName = env->NewStringUTF(strategy.getName().c_str());
    jStrategyId = static_cast<jint>(strategy.getId());

    // Audio Attributes Group array
    std::map<int, std::vector<AudioAttributes> > groups;
    for (const auto &attr : strategy.getAudioAttributes()) {
        int attrGroupId = attr.getGroupId();
        groups[attrGroupId].push_back(attr);
    }
    numAttributesGroups = groups.size();

    jAudioAttributesGroups = env->NewObjectArray(numAttributesGroups, gAudioAttributesGroupClass, NULL);

    for (const auto &iter : groups) {
        std::vector<AudioAttributes> audioAttributesGroups = iter.second;
        jint numAttributes = audioAttributesGroups.size();
        jint jGroupId = iter.first;
        jint jLegacyStreamType = audioAttributesGroups.front().getStreamType();

        jStatus = JNIAudioAttributeHelper::getJavaArray(env, &jAudioAttributes, numAttributes);
        if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
            goto exit;
        }
        for (size_t j = 0; j < static_cast<size_t>(numAttributes); j++) {
            auto attributes = audioAttributesGroups[j].getAttributes();

            jStatus = JNIAudioAttributeHelper::nativeToJava(env, &jAudioAttribute, attributes);
            if (jStatus != AUDIO_JAVA_SUCCESS) {
                goto exit;
            }
            env->SetObjectArrayElement(jAudioAttributes, j, jAudioAttribute);
        }
        jobject jAudioAttributesGroup = env->NewObject(gAudioAttributesGroupClass,
                                                       gAudioAttributesGroupCstor,
                                                       jGroupId,
                                                       jLegacyStreamType,
                                                       jAudioAttributes);
        env->SetObjectArrayElement(jAudioAttributesGroups, indexGroup++, jAudioAttributesGroup);

        if (jAudioAttributes != NULL) {
            env->DeleteLocalRef(jAudioAttributes);
            jAudioAttributes = NULL;
        }
        if (jAudioAttribute != NULL) {
            env->DeleteLocalRef(jAudioAttribute);
            jAudioAttribute = NULL;
        }
        if (jAudioAttributesGroup != NULL) {
            env->DeleteLocalRef(jAudioAttributesGroup);
            jAudioAttributesGroup = NULL;
        }
    }
    *jAudioStrategy = env->NewObject(gAudioProductStrategyClass, gAudioProductStrategyCstor,
                                     jName,
                                     jStrategyId,
                                     jAudioAttributesGroups);
exit:
    if (jAudioAttributes != NULL) {
        env->DeleteLocalRef(jAudioAttributes);
    }
    if (jAudioAttribute != NULL) {
        env->DeleteLocalRef(jAudioAttribute);
        jAudioAttribute = NULL;
    }
    if (jAudioAttributesGroups != NULL) {
        env->DeleteLocalRef(jAudioAttributesGroups);
    }
    if (jName != NULL) {
        env->DeleteLocalRef(jName);
    }
    return jStatus;
}

static jint
android_media_AudioSystem_listAudioProductStrategies(JNIEnv *env, jobject clazz,
                                                     jobject jStrategies)
{
    if (env == NULL) {
        return AUDIO_JAVA_DEAD_OBJECT;
    }
    if (jStrategies == NULL) {
        ALOGE("listAudioProductStrategies NULL AudioProductStrategies");
        return (jint)AUDIO_JAVA_BAD_VALUE;
    }
    if (!env->IsInstanceOf(jStrategies, gArrayListClass)) {
        ALOGE("listAudioProductStrategies not an arraylist");
        return (jint)AUDIO_JAVA_BAD_VALUE;
    }

    status_t status;
    AudioProductStrategyVector strategies;
    jint jStatus;
    jobject jStrategy = NULL;

    status = AudioSystem::listAudioProductStrategies(strategies);
    if (status != NO_ERROR) {
        ALOGE("AudioSystem::listAudioProductStrategies error %d", status);
        return nativeToJavaStatus(status);
    }
    for (const auto &strategy : strategies) {
        jStatus = convertAudioProductStrategiesFromNative(env, &jStrategy, strategy);
        if (jStatus != AUDIO_JAVA_SUCCESS) {
            goto exit;
        }
        env->CallBooleanMethod(jStrategies, gArrayListMethods.add, jStrategy);
    }
exit:
    if (jStrategy != NULL) {
        env->DeleteLocalRef(jStrategy);
    }
    return jStatus;
}

static jint
android_media_AudioSystem_getProductStrategyFromAudioAttributes(JNIEnv *env, jobject clazz,
                                                                jobject jAudioAttributes)
{
    JNIAudioAttributeHelper::UniqueAaPtr attributes = JNIAudioAttributeHelper::makeUnique();
    jint jStatus = JNIAudioAttributeHelper::nativeFromJava(env,
                                                           jAudioAttributes,
                                                           attributes.get());
    if (jStatus != (jint)AUDIO_JAVA_SUCCESS) {
        return jStatus;
    }
    product_strategy_t psId;
    status_t status = AudioSystem::getProductStrategyFromAudioAttributes(
                AudioAttributes(*attributes.get()), psId);
    if (status != NO_ERROR) {
        return nativeToJavaStatus(status);
    }
    return psId;
}

/*
 * JNI registration.
 */
static const JNINativeMethod gMethods[] = {
    {"native_list_audio_product_strategies", "(Ljava/util/ArrayList;)I",
                        (void *)android_media_AudioSystem_listAudioProductStrategies},
    {"native_get_product_strategies_from_audio_attributes", "(Landroid/media/AudioAttributes;)I",
                        (void *)android_media_AudioSystem_getProductStrategyFromAudioAttributes},
};

int register_android_media_AudioProductStrategies(JNIEnv *env)
{
    jclass arrayListClass = FindClassOrDie(env, "java/util/ArrayList");
    gArrayListClass = MakeGlobalRefOrDie(env, arrayListClass);
    gArrayListMethods.add = GetMethodIDOrDie(env, arrayListClass, "add", "(Ljava/lang/Object;)Z");
    gArrayListMethods.toArray = GetMethodIDOrDie(env, arrayListClass,
                                                 "toArray", "()[Ljava/lang/Object;");

    jclass audioProductStrategyClass = FindClassOrDie(env, kAudioProductStrategyClassPathName);
    gAudioProductStrategyClass = MakeGlobalRefOrDie(env, audioProductStrategyClass);
    gAudioProductStrategyCstor = GetMethodIDOrDie(
                env, audioProductStrategyClass, "<init>",
                "(Ljava/lang/String;I[Landroid/media/audiopolicy/AudioProductStrategy$AudioAttributesGroup;)V");
    gAudioProductStrategyFields.mAudioAttributesGroups = GetFieldIDOrDie(
                env, audioProductStrategyClass, "mAudioAttributesGroups",
                "[Landroid/media/audiopolicy/AudioProductStrategy$AudioAttributesGroup;");
    gAudioProductStrategyFields.mName = GetFieldIDOrDie(
                env, audioProductStrategyClass, "mName", "Ljava/lang/String;");
    gAudioProductStrategyFields.mId = GetFieldIDOrDie(
                env, audioProductStrategyClass, "mId", "I");

    jclass audioAttributesGroupClass = FindClassOrDie(env, kAudioAttributesGroupsClassPathName);
    gAudioAttributesGroupClass = MakeGlobalRefOrDie(env, audioAttributesGroupClass);
    gAudioAttributesGroupCstor = GetMethodIDOrDie(env, audioAttributesGroupClass, "<init>",
                                                  "(II[Landroid/media/AudioAttributes;)V");
    gAudioAttributesGroupsFields.mVolumeGroupId = GetFieldIDOrDie(
                env, audioAttributesGroupClass, "mVolumeGroupId", "I");
    gAudioAttributesGroupsFields.mLegacyStreamType = GetFieldIDOrDie(
                env, audioAttributesGroupClass, "mLegacyStreamType", "I");
    gAudioAttributesGroupsFields.mAudioAttributes = GetFieldIDOrDie(
                env, audioAttributesGroupClass, "mAudioAttributes",
                "[Landroid/media/AudioAttributes;");

    env->DeleteLocalRef(audioProductStrategyClass);
    env->DeleteLocalRef(audioAttributesGroupClass);

    return RegisterMethodsOrDie(env, kClassPathName, gMethods, NELEM(gMethods));
}
