/*
 * Copyright (C) 2010 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.
 */

/* AndroidConfiguration implementation */

#include <android/log.h>

#include "sles_allinclusive.h"
#include <SLES/OpenSLES_Android.h>

#include <android_runtime/AndroidRuntime.h>

static SLresult IAndroidConfiguration_SetConfiguration(SLAndroidConfigurationItf self,
        const SLchar *configKey,
        const void *pConfigValue,
        SLuint32 valueSize)
{
    SL_ENTER_INTERFACE

    // object-specific code will check that valueSize is large enough for the key
    if (NULL == configKey || NULL == pConfigValue || valueSize == 0) {
        result = SL_RESULT_PARAMETER_INVALID;

    } else {
        IAndroidConfiguration *thiz = (IAndroidConfiguration *) self;
        interface_lock_exclusive(thiz);

        // route configuration to the appropriate object
        switch (IObjectToObjectID((thiz)->mThis)) {
        case SL_OBJECTID_AUDIORECORDER:
            SL_LOGV("SetConfiguration issued for AudioRecorder key=%s valueSize=%u",
                    configKey, valueSize);
            result = android_audioRecorder_setConfig((CAudioRecorder *) thiz->mThis, configKey,
                    pConfigValue, valueSize);
            break;
        case SL_OBJECTID_AUDIOPLAYER:
            SL_LOGV("SetConfiguration issued for AudioPlayer key=%s valueSize=%u",
                    configKey, valueSize);
            result = android_audioPlayer_setConfig((CAudioPlayer *) thiz->mThis, configKey,
                    pConfigValue, valueSize);
            break;
        default:
            result = SL_RESULT_FEATURE_UNSUPPORTED;
            break;
        }

        interface_unlock_exclusive(thiz);
    }

    SL_LEAVE_INTERFACE
}


static SLresult IAndroidConfiguration_GetConfiguration(SLAndroidConfigurationItf self,
        const SLchar *configKey,
        SLuint32 *pValueSize,
        void *pConfigValue)
{
    SL_ENTER_INTERFACE

    // non-NULL pValueSize is required, but a NULL pConfigValue is allowed, so
    // that we can report the actual value size without returning the value itself
    if (NULL == configKey || NULL == pValueSize) {
        result = SL_RESULT_PARAMETER_INVALID;
    } else {
        IAndroidConfiguration *thiz = (IAndroidConfiguration *) self;
        interface_lock_exclusive(thiz);

        // route configuration request to the appropriate object
        switch (IObjectToObjectID((thiz)->mThis)) {
        case SL_OBJECTID_AUDIORECORDER:
            result = android_audioRecorder_getConfig((CAudioRecorder *) thiz->mThis, configKey,
                    pValueSize, pConfigValue);
            break;
        case SL_OBJECTID_AUDIOPLAYER:
            result = android_audioPlayer_getConfig((CAudioPlayer *) thiz->mThis, configKey,
                    pValueSize, pConfigValue);
        default:
            result = SL_RESULT_FEATURE_UNSUPPORTED;
            break;
        }

        interface_unlock_exclusive(thiz);
    }

    SL_LEAVE_INTERFACE
}

/*
 * Native Routing API
 */
static SLresult ValidatePlayerConfig(IAndroidConfiguration* iConfig) {
    SLresult result;

    if (iConfig->mRoutingProxy != NULL) {
        result = SL_RESULT_PRECONDITIONS_VIOLATED;
        SL_LOGE("Error creating player routing object - Routing Proxy Already Acquired.");
    }
    else {
        IObject* configObj = iConfig->mThis;                // get corresponding object
        CAudioPlayer* player = (CAudioPlayer*)configObj;    // get the native player

        switch (player->mAndroidObjType) {
            case AUDIOPLAYER_FROM_PCM_BUFFERQUEUE:
                //TODO remove these commented out lines when our comfort level is good
//                if (player->mObject.mState != SL_OBJECT_STATE_REALIZED) {
//                    // Make sure the player has been realized.
//                    result = SL_RESULT_PRECONDITIONS_VIOLATED;
//                    SL_LOGE("Error creating routing object - Player not realized.");
//                } else {
//                    android::AudioTrack* pAudioTrack = player->mAudioTrack.get();
//                    if (pAudioTrack == NULL) {
//                        result = SL_RESULT_INTERNAL_ERROR;
//                        SL_LOGE("Error creating routing object - Couldn't get AudioTrack.");
//                    } else {
                        result = SL_RESULT_SUCCESS;
//                    }
//                }
                break;

            default:
                result =  SL_RESULT_PARAMETER_INVALID;
                SL_LOGE("Error creating routing object - Player is not a buffer-queue player.");
                break;
        }
    }

    return result;
}

static SLresult AllocPlayerRoutingProxy(IAndroidConfiguration* iConfig, jobject* proxyObj) {
    SLresult result;

    IObject* configObj = iConfig->mThis;                // get corresponding object
    android::AudioTrack* pAudioTrack = ((CAudioPlayer*)configObj)->mTrackPlayer->mAudioTrack.get();

    JNIEnv* j_env = android::AndroidRuntime::getJNIEnv();

    // Get the constructor for (Java) AudioTrackRoutingProxy
    jclass clsAudioTrackRoutingProxy =
            j_env->FindClass("android/media/AudioTrackRoutingProxy");
    jmethodID midAudioTrackRoutingProxy_ctor =
        j_env->GetMethodID(clsAudioTrackRoutingProxy, "<init>", "(J)V");

    j_env->ExceptionClear();

    jobject localObjRef =
        j_env->NewObject(clsAudioTrackRoutingProxy,
                         midAudioTrackRoutingProxy_ctor,
                         (jlong)pAudioTrack /*audioTrackObjInLong*/);

    *proxyObj = j_env->NewGlobalRef(localObjRef);

    if (j_env->ExceptionCheck()) {
        SL_LOGE("Java exception creating player routing object.");
        result = SL_RESULT_INTERNAL_ERROR;
    } else {
        // stash it in the Interface object
        iConfig->mRoutingProxy = *proxyObj;
        result = SL_RESULT_SUCCESS;
    }

    return result;
}

static SLresult ValidateRecorderConfig(IAndroidConfiguration* iConfig) {
    SLresult result;

    if (iConfig->mRoutingProxy != NULL) {
        result = SL_RESULT_PRECONDITIONS_VIOLATED;
        SL_LOGE("Error creating record routing object - Routing Proxy Already Acquired.");
    } else {
        IObject* configObj = iConfig->mThis;                  // get corresponding object
        CAudioRecorder* recorder = (CAudioRecorder*)configObj;  // get the native recorder
        switch (recorder->mAndroidObjType) {
            case AUDIORECORDER_FROM_MIC_TO_PCM_BUFFERQUEUE:
                //TODO remove these commented out lines when our comfort level is good
//                if (recorder->mObject.mState != SL_OBJECT_STATE_REALIZED) {
//                    // Make sure the recorder has been realized.
//                    result = SL_RESULT_PRECONDITIONS_VIOLATED;
//                    SL_LOGE("Error creating routing object - Recorder not realized.");
//                } else {
//                    android::AudioRecord* pAudioRecord = recorder->mAudioRecord.get();
//                    if (pAudioRecord == NULL) {
//                        result = SL_RESULT_INTERNAL_ERROR;
//                        SL_LOGE("Error creating routing object - Couldn't get AudioRecord.");
//                    } else if (iConfig->mRoutingProxy != NULL) {
//                        result = SL_RESULT_PRECONDITIONS_VIOLATED;
//                        SL_LOGE("Error creating routing object - Routing Proxy Already Acquired.");
//                    } else {
                        result = SL_RESULT_SUCCESS;
//                    }
//                }
                break;

            default:
                result =  SL_RESULT_PARAMETER_INVALID;
                SL_LOGE("Error creating routing object - Recorder is not a buffer-queue recorder.");
                break;
        }
    }

    return result;
}

static SLresult AllocRecorderRoutingProxy(IAndroidConfiguration* iConfig, jobject* proxyObj) {
    SLresult result;

    IObject* configObj = iConfig->mThis;                  // get corresponding object
    android::AudioRecord* pAudioRecord = ((CAudioRecorder*)configObj)->mAudioRecord.get();

    JNIEnv* j_env = android::AndroidRuntime::getJNIEnv();

    // Get the constructor for (Java) AudioRecordRoutingProxy
    jclass clsAudioRecordRoutingProxy =
            j_env->FindClass("android/media/AudioRecordRoutingProxy");
    jmethodID midAudioRecordRoutingProxy_ctor =
        j_env->GetMethodID(clsAudioRecordRoutingProxy, "<init>", "(J)V");

    j_env->ExceptionClear();
    jobject localObjRef =
        j_env->NewObject(clsAudioRecordRoutingProxy,
                         midAudioRecordRoutingProxy_ctor,
                         (jlong)pAudioRecord /*audioRecordObjInLong*/);

    *proxyObj = j_env->NewGlobalRef(localObjRef);
    if (j_env->ExceptionCheck()) {
        SL_LOGE("Java exception creating recorder routing object.");
        result = SL_RESULT_INTERNAL_ERROR;
    } else {
        // stash it in the Interface object
        iConfig->mRoutingProxy = *proxyObj;
        result = SL_RESULT_SUCCESS;
    }

    return result;
}

/*
 * Acquires a Java proxy object, such as AudioRouting object which can be used to control
 * aspects of the associated native player or recorder.
 * Parameters:
 *   self   An SLAndroidConfigurationItf obtained from either an OpenSL ES AudioPlayer
 *          or AudioRecorder.
 *   j_env  The Java Environment pointer (passed in to the calling JNI function).
 *   proxyType Specifies the type of proxy desired. Currently only SL_ANDROID_JAVA_PROXY_ROUTING
 *          is supported.
 *   proxyObj
 *          Points to the jobject to receive the acquired Java proxy object (as a GlobalRef).
 * Returns SL_RESULT_SUCCESS is the proxy object is acquired, SL_RESULT_PARAMETER_INVALID if
 *   there is a problem with the arguments causing the function to fail,
 *   <working on this>
 *   SL_RESULT_PRECONDITIONS_VIOLATED it the AudioPlayer or AudioRecorder object associated
 *   with the ConfigurationItf has not been realized.
 */
static SLresult IAndroidConfiguration_AcquireJavaProxy(SLAndroidConfigurationItf self,
                                                       SLuint32 proxyType,
                                                       jobject* proxyObj)
{
    SL_ENTER_INTERFACE

    if (self == NULL || proxyObj == NULL || proxyType != SL_ANDROID_JAVA_PROXY_ROUTING) {
        result =  SL_RESULT_PARAMETER_INVALID;
    } else {
        IAndroidConfiguration* iConfig = (IAndroidConfiguration*)self;

        int objID = IObjectToObjectID(InterfaceToIObject(iConfig));
        switch (objID) {
        case SL_OBJECTID_AUDIOPLAYER:
            result = ValidatePlayerConfig(iConfig);
            if (result == SL_RESULT_SUCCESS) {
                result = AllocPlayerRoutingProxy(iConfig, proxyObj);
            }
            break;

        case SL_OBJECTID_AUDIORECORDER:
            result = ValidateRecorderConfig(iConfig);
            if (result == SL_RESULT_SUCCESS) {
                result = AllocRecorderRoutingProxy(iConfig, proxyObj);
            }
            break;

        default:
            result = SL_RESULT_PARAMETER_INVALID;
            break;
        }
    }

    SL_LEAVE_INTERFACE
}

/*
 * Release a Java proxy object, such as AudioRouting object, (and any resources it is holding).
 * Parameters:
 *   self   An SLAndroidConfigurationItf obtained from either an OpenSL ES AudioPlayer
 *          or AudioRecorder.
 *   j_env  The Java Environment pointer (passed in to the calling JNI function).
 *   proxyType Specifies the type of proxy object. Currently only SL_ANDROID_JAVA_PROXY_ROUTING
 *          is supported.
 * Returns SL_RESULT_SUCCESS is the proxy object is release, SL_RESULT_PARAMETER_INVALID if
 *   there is a problem with the arguments causing the function to fail,
 */
static SLresult IAndroidConfiguration_ReleaseJavaProxy(SLAndroidConfigurationItf self,
                                                       SLuint32 proxyType) {
    SL_ENTER_INTERFACE

    IAndroidConfiguration* iConfig = (IAndroidConfiguration*)self;

    if (self == NULL ||
            proxyType != SL_ANDROID_JAVA_PROXY_ROUTING ||
            iConfig->mRoutingProxy == NULL) {
        result =  SL_RESULT_PARAMETER_INVALID;
    } else {
        int objID = IObjectToObjectID(InterfaceToIObject(iConfig));
        switch (objID) {
        case SL_OBJECTID_AUDIOPLAYER:
            {
                JNIEnv* j_env = android::AndroidRuntime::getJNIEnv();

                // Get the release method for (Java) AudioTrackRoutingProxy
                jclass clsAudioTrackRoutingProxy =
                        j_env->FindClass("android/media/AudioTrackRoutingProxy");
                jmethodID midAudioTrackRoutingProxy_release =
                    j_env->GetMethodID(clsAudioTrackRoutingProxy, "native_release", "()V");

                j_env->ExceptionClear();
                j_env->CallVoidMethod(iConfig->mRoutingProxy, midAudioTrackRoutingProxy_release);
                if (j_env->ExceptionCheck()) {
                    SL_LOGE("Java exception releasing recorder routing object.");
                    result = SL_RESULT_INTERNAL_ERROR;
                }
                j_env->DeleteGlobalRef(iConfig->mRoutingProxy);
                iConfig->mRoutingProxy = NULL;
            }
            break;

        case SL_OBJECTID_AUDIORECORDER:
            {
                JNIEnv* j_env = android::AndroidRuntime::getJNIEnv();

                // Get the release method for (Java) AudioTrackRoutingProxy
                jclass clsAudioRecordRoutingProxy =
                        j_env->FindClass("android/media/AudioRecordRoutingProxy");
                jmethodID midAudioRecordRoutingProxy_release =
                    j_env->GetMethodID(clsAudioRecordRoutingProxy, "native_release", "()V");

                j_env->ExceptionClear();
                j_env->CallVoidMethod(iConfig->mRoutingProxy, midAudioRecordRoutingProxy_release);
                if (j_env->ExceptionCheck()) {
                    SL_LOGE("Java exception releasing recorder routing object.");
                    result = SL_RESULT_INTERNAL_ERROR;
                }
                j_env->DeleteGlobalRef(iConfig->mRoutingProxy);
                iConfig->mRoutingProxy = NULL;
            }
            break;
        }

        result = SL_RESULT_SUCCESS;
    }

    SL_LEAVE_INTERFACE
}

static const struct SLAndroidConfigurationItf_ IAndroidConfiguration_Itf = {
    IAndroidConfiguration_SetConfiguration,
    IAndroidConfiguration_GetConfiguration,
    IAndroidConfiguration_AcquireJavaProxy,
    IAndroidConfiguration_ReleaseJavaProxy
};

void IAndroidConfiguration_init(void *self)
{
    IAndroidConfiguration *thiz = (IAndroidConfiguration *) self;
    thiz->mItf = &IAndroidConfiguration_Itf;
}

void IAndroidConfiguration_deinit(void *self)
{
    IAndroidConfiguration *thiz = (IAndroidConfiguration *) self;
    if (thiz->mRoutingProxy != NULL) {
        thiz->mItf->ReleaseJavaProxy(&thiz->mItf, SL_ANDROID_JAVA_PROXY_ROUTING);
    }
}

