/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <android/log.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "webrtc/voice_engine/test/android/android_test/jni/org_webrtc_voiceengine_test_AndroidTest.h"

#include "webrtc/base/platform_thread.h"

#include "webrtc/voice_engine/include/voe_audio_processing.h"
#include "webrtc/voice_engine/include/voe_base.h"
#include "webrtc/voice_engine/include/voe_codec.h"
#include "webrtc/voice_engine/include/voe_file.h"
#include "webrtc/voice_engine/include/voe_hardware.h"
#include "webrtc/voice_engine/include/voe_network.h"
#include "webrtc/voice_engine/include/voe_rtp_rtcp.h"
#include "webrtc/voice_engine/include/voe_volume_control.h"

#include "webrtc/voice_engine/test/auto_test/voe_test_interface.h"

//#define INIT_FROM_THREAD
//#define START_CALL_FROM_THREAD

#define WEBRTC_LOG_TAG "*WEBRTCN*" // As in WEBRTC Native...
#define VALIDATE_BASE_POINTER \
    if (!veData1.base) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "Base pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_CODEC_POINTER \
    if (!veData1.codec) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "Codec pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_FILE_POINTER \
    if (!veData1.file) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "File pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_NETWORK_POINTER \
    if (!veData1.netw) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "Network pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_APM_POINTER \
    if (!veData1.codec) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "Apm pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_VOLUME_POINTER \
    if (!veData1.volume) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "Volume pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_HARDWARE_POINTER \
    if (!veData1.hardware) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "Hardware pointer doesn't exist"); \
        return -1; \
    }
#define VALIDATE_RTP_RTCP_POINTER \
    if (!veData1.rtp_rtcp) \
    { \
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, \
                            "RTP / RTCP pointer doesn't exist"); \
        return -1; \
    }

// Register functions in JNI_OnLoad()
// How do we ensure that VoE is deleted? JNI_OnUnload?
// What happens if class is unloaded? When loaded again, NativeInit will be
// called again. Keep what we have?
// Should we do something in JNI_OnUnload?
// General design: create a class or keep global struct with "C" functions?
// Otherwise make sure symbols are as unique as possible.

// TestType enumerator
enum TestType
{
  Invalid = -1,
  Standard = 0,
  Extended = 1,
  Stress   = 2,
  Unit     = 3,
  CPU      = 4
};

using namespace webrtc;

class my_transportation;

// VoiceEngine data struct
typedef struct
{
    // VoiceEngine
    VoiceEngine* ve;
    // Sub-APIs
    VoEBase* base;
    VoECodec* codec;
    VoEFile* file;
    VoENetwork* netw;
    VoEAudioProcessing* apm;
    VoEVolumeControl* volume;
    VoEHardware* hardware;
    VoERTP_RTCP* rtp_rtcp;
    // Other
    my_transportation* extTrans;
    JavaVM* jvm;
} VoiceEngineData;

// my_transportation is used when useExtTrans is enabled
class my_transportation : public Transport
{
 public:
  my_transportation(VoENetwork * network) :
      netw(network) {
  }

  int SendPacket(int channel, const void* data, size_t len) override;
  int SendRTCPPacket(int channel, const void* data, size_t len) override;

 private:
  VoENetwork * netw;
};

int my_transportation::SendPacket(int channel, const void *data, size_t len)
{
  netw->ReceivedRTPPacket(channel, data, len);
  return len;
}

int my_transportation::SendRTCPPacket(int channel, const void *data, size_t len)
{
  netw->ReceivedRTCPPacket(channel, data, len);
  return len;
}

//Global variables visible in this file
static VoiceEngineData veData1;
static VoiceEngineData veData2;

// "Local" functions (i.e. not Java accessible)
static bool GetSubApis(VoiceEngineData &veData);
static bool ReleaseSubApis(VoiceEngineData &veData);

class ThreadTest
{
public:
    ThreadTest();
    ~ThreadTest();
    int RunTest();
    int CloseTest();
private:
    static bool Run(void* ptr);
    bool Process();
private:
    rtc::scoped_ptr<PlatformThread> _thread;
};

ThreadTest::~ThreadTest()
{
    if (_thread)
        _thread->Stop();
}

ThreadTest::ThreadTest()
{
    _thread = PlatformThread::CreateThread(Run, this, "ThreadTest thread");
}

bool ThreadTest::Run(void* ptr)
{
    return static_cast<ThreadTest*> (ptr)->Process();
}

bool ThreadTest::Process()
{
    // Attach this thread to JVM
    /*JNIEnv* env = NULL;
     jint res = veData1.jvm->AttachCurrentThread(&env, NULL);
     char msg[32];
     sprintf(msg, "res=%d, env=%d", res, env);
     __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG, msg);*/

#ifdef INIT_FROM_THREAD
    VALIDATE_BASE_POINTER;
    veData1.base->Init();
#endif

#ifdef START_CALL_FROM_THREAD
    // receiving instance
    veData2.ve = VoiceEngine::Create();
    GetSubApis(veData2);
    veData2.base->Init();
    veData2.base->CreateChannel();
    if(veData2.base->SetLocalReceiver(0, 1234) < 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                "set local receiver 2 failed");
    }
    veData2.volume->SetSpeakerVolume(204);
    veData2.base->StartReceive(0);
    if(veData2.base->StartPlayout(0) < 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                "start playout failed");
    }

    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
            "receiving instance started from thread");

    // sending instance
    veData1.ve = VoiceEngine::Create();
    GetSubApis(veData1);
    veData1.base->Init();
    if(veData1.base->CreateChannel() < 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                "create channel failed");
    }
    if(veData1.base->SetLocalReceiver(0, 1256) < 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                "set local receiver failed");
    }
    if(veData1.base->SetSendDestination(0, 1234, "127.0.0.1") < 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                "set send destination failed");
    }
    if(veData1.base->StartSend(0) < 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                "start send failed");
    }

    __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
            "sending instance started from thread");
#endif

    _thread->Stop();

    //res = veData1.jvm->DetachCurrentThread();

    return true;
}

int ThreadTest::RunTest()
{
    if (_thread)
    {
        _thread->Start();
    }
    return 0;
}

int ThreadTest::CloseTest()
{
    VALIDATE_BASE_POINTER

    veData1.base->DeleteChannel(0);
    veData2.base->DeleteChannel(0);
    veData1.base->Terminate();
    veData2.base->Terminate();

    // Release sub-APIs
    ReleaseSubApis(veData1);
    ReleaseSubApis(veData2);

    // Delete
    VoiceEngine::Delete(veData1.ve);
    VoiceEngine::Delete(veData2.ve);
    veData2.ve = NULL;
    veData2.ve = NULL;

    return 0;
}

ThreadTest threadTest;

//////////////////////////////////////////////////////////////////
// General functions
//////////////////////////////////////////////////////////////////

/////////////////////////////////////////////
// JNI_OnLoad
//
jint JNI_OnLoad(JavaVM* vm, void* /*reserved*/)
{
    if (!vm)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "JNI_OnLoad did not receive a valid VM pointer");
        return -1;
    }

    // Get JNI
    JNIEnv* env;
    if (JNI_OK != vm->GetEnv(reinterpret_cast<void**> (&env),
                             JNI_VERSION_1_4))
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "JNI_OnLoad could not get JNI env");
        return -1;
    }

    // Get class to register the native functions with
    // jclass regClass = env->FindClass("webrtc/android/AndroidTest");
    // if (!regClass) {
    // return -1; // Exception thrown
    // }

    // Register native functions
    // JNINativeMethod methods[1];
    // methods[0].name = NULL;
    // methods[0].signature = NULL;
    // methods[0].fnPtr = NULL;
    // if (JNI_OK != env->RegisterNatives(regClass, methods, 1))
    // {
    // return -1;
    // }

    // Init VoiceEngine data
    memset(&veData1, 0, sizeof(veData1));
    memset(&veData2, 0, sizeof(veData2));

    // Store the JVM
    veData1.jvm = vm;
    veData2.jvm = vm;

    return JNI_VERSION_1_4;
}

/////////////////////////////////////////////
// Native initialization
//
JNIEXPORT jboolean JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_NativeInit(
        JNIEnv * env,
        jclass)
{
    // Look up and cache any interesting class, field and method IDs for
    // any used java class here

    return true;
}

/////////////////////////////////////////////
// Run auto standard test
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_RunAutoTest(
        JNIEnv *env,
        jobject context,
        jint testType,
        jint extendedSel)
{
    TestType tType(Invalid);

    switch (testType)
    {
        case 0:
            return 0;
        case 1:
            tType = Standard;
            break;
        case 2:
            tType = Extended;
            break;
        case 3:
            tType = Stress;
            break;
        case 4:
            tType = Unit;
            break;
        default:
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "RunAutoTest - Invalid TestType");
            return -1;
    }

    // Set instance independent Java objects
    VoiceEngine::SetAndroidObjects(veData1.jvm, env, context);

    // Call voe test interface function
    // TODO(leozwang) add autotest setAndroidObjects(veData1.jvm, context);
    // jint retVal = runAutoTest(tType);

    // Clear instance independent Java objects
    VoiceEngine::SetAndroidObjects(NULL, NULL, NULL);

    return 0;
}

//////////////////////////////////////////////////////////////////
// VoiceEngine API wrapper functions
//////////////////////////////////////////////////////////////////

/////////////////////////////////////////////
// Create VoiceEngine instance
//
JNIEXPORT jboolean JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_Create(
        JNIEnv *env,
        jobject context)
{
    // Check if already created
    if (veData1.ve)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "VoE already created");
        return false;
    }

    // Set instance independent Java objects
    VoiceEngine::SetAndroidObjects(veData1.jvm, env, context);

#ifdef START_CALL_FROM_THREAD
    threadTest.RunTest();
#else
    // Create
    veData1.ve = VoiceEngine::Create();
    if (!veData1.ve)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Create VoE failed");
        return false;
    }

    // Get sub-APIs
    if (!GetSubApis(veData1))
    {
        // If not OK, release all sub-APIs and delete VoE
        ReleaseSubApis(veData1);
        if (!VoiceEngine::Delete(veData1.ve))
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Delete VoE failed");
        }
        return false;
    }
#endif

    return true;
}

/////////////////////////////////////////////
// Delete VoiceEngine instance
//
JNIEXPORT jboolean JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_Delete(
        JNIEnv *,
        jobject)
{
#ifdef START_CALL_FROM_THREAD
    threadTest.CloseTest();
#else
    // Check if exists
    if (!veData1.ve)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "VoE does not exist");
        return false;
    }

    // Release sub-APIs
    ReleaseSubApis(veData1);

    // Delete
    if (!VoiceEngine::Delete(veData1.ve))
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Delete VoE failed");
        return false;
    }

    veData1.ve = NULL;
#endif

    // Clear instance independent Java objects
    VoiceEngine::SetAndroidObjects(NULL, NULL, NULL);

    return true;
}

/////////////////////////////////////////////
// [Base] Initialize VoiceEngine
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_Init(
        JNIEnv *,
        jobject,
        jboolean enableTrace,
        jboolean useExtTrans)
{
    VALIDATE_BASE_POINTER;

    if (enableTrace)
    {
        if (0 != VoiceEngine::SetTraceFile("/sdcard/trace.txt"))
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Could not enable trace");
        }
        if (0 != VoiceEngine::SetTraceFilter(kTraceAll))
        {
            __android_log_write(ANDROID_LOG_WARN, WEBRTC_LOG_TAG,
                                "Could not set trace filter");
        }
    }

    if (useExtTrans)
    {
        VALIDATE_NETWORK_POINTER;
        veData1.extTrans = new my_transportation(veData1.netw);
    }

    int retVal = 0;
#ifdef INIT_FROM_THREAD
    threadTest.RunTest();
    usleep(200000);
#else
    retVal = veData1.base->Init();
#endif
    return retVal;
}

/////////////////////////////////////////////
// [Base] Terminate VoiceEngine
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_Terminate(
        JNIEnv *,
        jobject)
{
    VALIDATE_BASE_POINTER;

    jint retVal = veData1.base->Terminate();

    delete veData1.extTrans;
    veData1.extTrans = NULL;

    return retVal;
}

/////////////////////////////////////////////
// [Base] Create channel
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_CreateChannel(
        JNIEnv *,
        jobject)
{
    VALIDATE_BASE_POINTER;
    jint channel = veData1.base->CreateChannel();

    if (veData1.extTrans)
    {
        VALIDATE_NETWORK_POINTER;
        __android_log_print(ANDROID_LOG_DEBUG, WEBRTC_LOG_TAG,
                            "Enabling external transport on channel %d",
                            channel);
        if (veData1.netw->RegisterExternalTransport(channel, *veData1.extTrans)
                < 0)
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Could not set external transport");
            return -1;
        }
    }

    return channel;
}

/////////////////////////////////////////////
// [Base] Delete channel
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_DeleteChannel(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_BASE_POINTER;
    return veData1.base->DeleteChannel(channel);
}

/////////////////////////////////////////////
// [Base] SetLocalReceiver
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_SetLocalReceiver(
        JNIEnv *,
        jobject,
        jint channel,
        jint port)
{
    VALIDATE_BASE_POINTER;
    return veData1.base->SetLocalReceiver(channel, port);
}

/////////////////////////////////////////////
// [Base] SetSendDestination
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_SetSendDestination(
        JNIEnv *env,
        jobject,
        jint channel,
        jint port,
        jstring ipaddr)
{
    VALIDATE_BASE_POINTER;

    const char* ipaddrNative = env->GetStringUTFChars(ipaddr, NULL);
    if (!ipaddrNative)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Could not get UTF string");
        return -1;
    }

    jint retVal = veData1.base->SetSendDestination(channel, port, ipaddrNative);

    env->ReleaseStringUTFChars(ipaddr, ipaddrNative);

    return retVal;
}

/////////////////////////////////////////////
// [Base] StartListen
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StartListen(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_BASE_POINTER;
    int retVal = veData1.base->StartReceive(channel);

    return retVal;
}

/////////////////////////////////////////////
// [Base] Start playout
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StartPlayout(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_BASE_POINTER;
    int retVal = veData1.base->StartPlayout(channel);

    return retVal;
}

/////////////////////////////////////////////
// [Base] Start send
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StartSend(
        JNIEnv *,
        jobject,
        jint channel)
{
    /*    int dscp(0), serviceType(-1), overrideDscp(0), res(0);
     bool gqosEnabled(false), useSetSockOpt(false);

     if (veData1.netw->SetSendTOS(channel, 13, useSetSockOpt) != 0)
     {
     __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
         "Failed to set TOS");
     return -1;
     }

     res = veData1.netw->GetSendTOS(channel, dscp, useSetSockOpt);
     if (res != 0 || dscp != 13 || useSetSockOpt != true)
     {
     __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
         "Failed to get TOS");
     return -1;
     } */

    /* if (veData1.rtp_rtcp->SetREDStatus(channel, 1) != 0)
     {
     __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
         "Failed to enable RED");
     return -1;
     } */

    VALIDATE_BASE_POINTER;
    int retVal = veData1.base->StartSend(channel);

    return retVal;
}

/////////////////////////////////////////////
// [Base] Stop listen
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StopListen(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_BASE_POINTER;
    return veData1.base->StopReceive(channel);
}

/////////////////////////////////////////////
// [Base] Stop playout
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StopPlayout(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_BASE_POINTER;
    return veData1.base->StopPlayout(channel);
}

/////////////////////////////////////////////
// [Base] Stop send
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_StopSend(
        JNIEnv *,
        jobject,
        jint channel)
{
    /* if (veData1.rtp_rtcp->SetREDStatus(channel, 0) != 0)
     {
     __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
         "Failed to disable RED");
     return -1;
     } */

    VALIDATE_BASE_POINTER;
    return veData1.base->StopSend(channel);
}

/////////////////////////////////////////////
// [codec] Number of codecs
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_NumOfCodecs(
        JNIEnv *,
        jobject)
{
    VALIDATE_CODEC_POINTER;
    return veData1.codec->NumOfCodecs();
}

/////////////////////////////////////////////
// [codec] Set send codec
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_SetSendCodec(
        JNIEnv *,
        jobject,
        jint channel,
        jint index)
{
    VALIDATE_CODEC_POINTER;

    CodecInst codec;

    if (veData1.codec->GetCodec(index, codec) != 0)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Failed to get codec");
        return -1;
    }

    return veData1.codec->SetSendCodec(channel, codec);
}

/////////////////////////////////////////////
// [codec] Set VAD status
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_SetVADStatus(
        JNIEnv *,
        jobject,
        jint channel,
        jboolean enable,
        jint mode)
{
    VALIDATE_CODEC_POINTER;

    VadModes VADmode = kVadConventional;

    switch (mode)
    {
        case 0:
            break; // already set
        case 1:
            VADmode = kVadAggressiveLow;
            break;
        case 2:
            VADmode = kVadAggressiveMid;
            break;
        case 3:
            VADmode = kVadAggressiveHigh;
            break;
        default:
            VADmode = (VadModes) 17; // force error
            break;
    }

    return veData1.codec->SetVADStatus(channel, enable, VADmode);
}

/////////////////////////////////////////////
// [apm] SetNSStatus
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_SetNSStatus(
        JNIEnv *,
        jobject,
        jboolean enable,
        jint mode)
{
    VALIDATE_APM_POINTER;

    NsModes NSmode = kNsDefault;

    switch (mode)
    {
        case 0:
            NSmode = kNsUnchanged;
            break;
        case 1:
            break; // already set
        case 2:
            NSmode = kNsConference;
            break;
        case 3:
            NSmode = kNsLowSuppression;
            break;
        case 4:
            NSmode = kNsModerateSuppression;
            break;
        case 5:
            NSmode = kNsHighSuppression;
            break;
        case 6:
            NSmode = kNsVeryHighSuppression;
            break;
        default:
            NSmode = (NsModes) 17; // force error
            break;
    }

    return veData1.apm->SetNsStatus(enable, NSmode);
}

/////////////////////////////////////////////
// [apm] SetAGCStatus
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_SetAGCStatus(
        JNIEnv *,
        jobject,
        jboolean enable,
        jint mode)
{
    VALIDATE_APM_POINTER;

    AgcModes AGCmode = kAgcDefault;

    switch (mode)
    {
        case 0:
            AGCmode = kAgcUnchanged;
            break;
        case 1:
            break; // already set
        case 2:
            AGCmode = kAgcAdaptiveAnalog;
            break;
        case 3:
            AGCmode = kAgcAdaptiveDigital;
            break;
        case 4:
            AGCmode = kAgcFixedDigital;
            break;
        default:
            AGCmode = (AgcModes) 17; // force error
            break;
    }

    /* AgcConfig agcConfig;
     agcConfig.targetLeveldBOv = 3;
     agcConfig.digitalCompressionGaindB = 50;
     agcConfig.limiterEnable = 0;

     if (veData1.apm->SetAGCConfig(agcConfig) != 0)
     {
     __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
         "Failed to set AGC config");
     return -1;
     } */

    return veData1.apm->SetAgcStatus(enable, AGCmode);
}

/////////////////////////////////////////////
// [apm] SetECStatus
//
JNIEXPORT jint JNICALL Java_org_webrtc_voiceengine_test_AndroidTest_SetECStatus(
        JNIEnv *,
        jobject,
        jboolean enable,
        jint mode)
{
    VALIDATE_APM_POINTER;

    EcModes ECmode = kEcDefault;

    switch (mode)
    {
        case 0:
            ECmode = kEcDefault;
            break;
        case 1:
            break; // already set
        case 2:
            ECmode = kEcConference;
            break;
        case 3:
            ECmode = kEcAec;
            break;
        case 4:
            ECmode = kEcAecm;
            break;
        default:
            ECmode = (EcModes) 17; // force error
            break;
    }

    return veData1.apm->SetEcStatus(enable, ECmode);
}

/////////////////////////////////////////////
// [File] Start play file locally
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StartPlayingFileLocally(
        JNIEnv * env,
        jobject,
        jint channel,
        jstring fileName,
        jboolean loop)
{
    VALIDATE_FILE_POINTER;

    const char* fileNameNative = env->GetStringUTFChars(fileName, NULL);
    if (!fileNameNative)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Could not get UTF string");
        return -1;
    }

    jint retVal = veData1.file->StartPlayingFileLocally(channel,
                                                        fileNameNative, loop);

    env->ReleaseStringUTFChars(fileName, fileNameNative);

    return retVal;
}

/////////////////////////////////////////////
// [File] Stop play file locally
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StopPlayingFileLocally(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_FILE_POINTER;
    return veData1.file->StopPlayingFileLocally(channel);
}

/*
 * Class:     org_webrtc_voiceengine_test_AndroidTest
 * Method:    StartRecordingPlayout
 * Signature: (ILjava/lang/String;Z)I
 */
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StartRecordingPlayout(
        JNIEnv * env,
        jobject,
        jint channel,
        jstring fileName,
        jboolean)
{
    VALIDATE_FILE_POINTER;

    const char* fileNameNative = env->GetStringUTFChars(fileName, NULL);
    if (!fileNameNative)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Could not get UTF string");
        return -1;
    }

    jint retVal = veData1.file->StartRecordingPlayout(channel, fileNameNative,
                                                      0);

    env->ReleaseStringUTFChars(fileName, fileNameNative);

    return retVal;
}

/////////////////////////////////////////////
// [File] Stop Recording Playout
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StopRecordingPlayout(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_FILE_POINTER;
    return veData1.file->StopRecordingPlayout(channel);
}

/////////////////////////////////////////////
// [File] Start playing file as microphone
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StartPlayingFileAsMicrophone(
        JNIEnv *env,
        jobject,
        jint channel,
        jstring fileName,
        jboolean loop)
{
    VALIDATE_FILE_POINTER;

    const char* fileNameNative = env->GetStringUTFChars(fileName, NULL);
    if (!fileNameNative)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Could not get UTF string");
        return -1;
    }

    jint retVal = veData1.file->StartPlayingFileAsMicrophone(channel,
                                                             fileNameNative,
                                                             loop);

    env->ReleaseStringUTFChars(fileName, fileNameNative);

    return retVal;
}

/////////////////////////////////////////////
// [File] Stop playing file as microphone
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_StopPlayingFileAsMicrophone(
        JNIEnv *,
        jobject,
        jint channel)
{
    VALIDATE_FILE_POINTER;
    return veData1.file->StopPlayingFileAsMicrophone(channel);
}

/////////////////////////////////////////////
// [Volume] Set speaker volume
//
JNIEXPORT jint JNICALL
Java_org_webrtc_voiceengine_test_AndroidTest_SetSpeakerVolume(
        JNIEnv *,
        jobject,
        jint level)
{
    VALIDATE_VOLUME_POINTER;
    if (veData1.volume->SetSpeakerVolume(level) != 0)
    {
        return -1;
    }

    unsigned int storedVolume = 0;
    if (veData1.volume->GetSpeakerVolume(storedVolume) != 0)
    {
        return -1;
    }

    if (storedVolume != level)
    {
        return -1;
    }

    return 0;
}

//////////////////////////////////////////////////////////////////
// "Local" functions (i.e. not Java accessible)
//////////////////////////////////////////////////////////////////

/////////////////////////////////////////////
// Get all sub-APIs
//
bool GetSubApis(VoiceEngineData &veData)
{
    bool getOK = true;

    // Base
    veData.base = VoEBase::GetInterface(veData.ve);
    if (!veData.base)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get base sub-API failed");
        getOK = false;
    }

    // Codec
    veData.codec = VoECodec::GetInterface(veData.ve);
    if (!veData.codec)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get codec sub-API failed");
        getOK = false;
    }

    // File
    veData.file = VoEFile::GetInterface(veData.ve);
    if (!veData.file)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get file sub-API failed");
        getOK = false;
    }

    // Network
    veData.netw = VoENetwork::GetInterface(veData.ve);
    if (!veData.netw)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get network sub-API failed");
        getOK = false;
    }

    // AudioProcessing module
    veData.apm = VoEAudioProcessing::GetInterface(veData.ve);
    if (!veData.apm)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get apm sub-API failed");
        getOK = false;
    }

    // Volume
    veData.volume = VoEVolumeControl::GetInterface(veData.ve);
    if (!veData.volume)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get volume sub-API failed");
        getOK = false;
    }

    // Hardware
    veData.hardware = VoEHardware::GetInterface(veData.ve);
    if (!veData.hardware)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get hardware sub-API failed");
        getOK = false;
    }

    // RTP / RTCP
    veData.rtp_rtcp = VoERTP_RTCP::GetInterface(veData.ve);
    if (!veData.rtp_rtcp)
    {
        __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                            "Get rtp_rtcp sub-API failed");
        getOK = false;
    }

    return getOK;
}

/////////////////////////////////////////////
// Release all sub-APIs
//
bool ReleaseSubApis(VoiceEngineData &veData)
{
    bool releaseOK = true;

    // Base
    if (veData.base)
    {
        if (0 != veData.base->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release base sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.base = NULL;
        }
    }

    // Codec
    if (veData.codec)
    {
        if (0 != veData.codec->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release codec sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.codec = NULL;
        }
    }

    // File
    if (veData.file)
    {
        if (0 != veData.file->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release file sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.file = NULL;
        }
    }

    // Network
    if (veData.netw)
    {
        if (0 != veData.netw->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release network sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.netw = NULL;
        }
    }

    // apm
    if (veData.apm)
    {
        if (0 != veData.apm->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release apm sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.apm = NULL;
        }
    }

    // Volume
    if (veData.volume)
    {
        if (0 != veData.volume->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release volume sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.volume = NULL;
        }
    }

    // Hardware
    if (veData.hardware)
    {
        if (0 != veData.hardware->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release hardware sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.hardware = NULL;
        }
    }

    // RTP RTCP
    if (veData.rtp_rtcp)
    {
        if (0 != veData.rtp_rtcp->Release())
        {
            __android_log_write(ANDROID_LOG_ERROR, WEBRTC_LOG_TAG,
                                "Release rtp_rtcp sub-API failed");
            releaseOK = false;
        }
        else
        {
            veData.rtp_rtcp = NULL;
        }
    }

    return releaseOK;
}
