#include "AudioParamParserPriv.h"

#include <assert.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

#ifdef __linux__
#include <dirent.h>
#include <unistd.h>
#else
#include <windows.h>
#pragma warning( disable : 4996 )
#endif

static AppHandle appHandleInst;
static int appHandleInited = 0;

#ifdef FORCE_DEBUG_LEVEL
int appDebugLevel = DEBUG_LEVEL;        /* Global debug level setting */
#else
int appDebugLevel = INFO_LEVEL;         /* Global debug level setting */
#endif

FILE *appLogFp = NULL;
int outputLogToStdout = 0;

#ifndef WIN32
static pthread_rwlock_t appHandleInstLock = PTHREAD_RWLOCK_INITIALIZER;
static const char *appHandleInstLockCallerFun = NULL;  /* Used to cache the lock holder */
#else
int __stdcall DllMain(HINSTANCE hInstance, DWORD dwReason, PVOID pvReserved)
{
    return TRUE;
}
#endif

EXPORT APP_STATUS appHandleInit(AppHandle *appHandle)
{
#ifdef _DEBUG
    /* Alwasy show the output console for debug build */
    appHandleRedirectIOToConsole();
#endif

    INFO_LOG("appHandle = 0x%p\n", appHandle);

    if (appHandle)
    {
        appHandle->xmlDir = NULL;
        appHandle->xmlCusDir = NULL;
        appHandle->audioTypeHash = NULL;
        appHandle->featureOptionsHash = NULL;
        appHandle->featureOptionsDoc = NULL;
        appHandle->noficyCbList = NULL;
#ifndef WIN32
        appHandle->lockCallerFun = NULL;
        appHandle->appThreadExit = 0;
        appHandle->inotifyFd = 0;

        pthread_rwlock_init(&appHandle->lock, NULL);
#endif
        appHandleShowAudioTypeSupportedVerInfo(appHandle);
        return APP_NO_ERROR;
    }
    else
    {
        WARN_LOG("AppHandle is NULL!\n");
        return APP_ERROR;
    }
}

EXPORT APP_STATUS appHandleUninit(AppHandle *appHandle)
{
    INFO_LOG("appHandle = 0x%p\n", appHandle);

    if (!appHandle)
    {
        WARN_LOG("AppHandle is NULL!\n");
        return APP_ERROR;
    }
    else
    {
        NotifyCb *notifyCb, *tmp;

        /* Lock */
        appHandleWriteLock(appHandle, __FUNCTION__);

        if (appHandle->xmlDir)
        {
            free(appHandle->xmlDir);
        }
        appHandle->xmlDir = NULL;

        if (appHandle->xmlCusDir)
        {
            free(appHandle->xmlCusDir);
        }
        appHandle->xmlCusDir = NULL;

        if (appHandle->featureOptionsDoc)
        {
            xmlFreeDoc(appHandle->featureOptionsDoc);
        }
        appHandle->featureOptionsDoc = NULL;

#ifndef WIN32
        if (appHandle->appThreadExit == 0)
        {
            void *status;
            appHandle->appThreadExit = 1;
            INFO_LOG("Send signal to appThread\n");
            pthread_kill(appHandle->appThread, SIGUSR1);

            /* TODO: Don't join the inotify thread, since the read function is block waiting */
            INFO_LOG("Waiting inotify thread join...\n");
            pthread_join(appHandle->appThread, &status);
            INFO_LOG("inotify thread joined\n");
            appHandle->inotifyFd = 0;
        }
#endif

        // release notify callback list
        LL_FOREACH_SAFE(appHandle->noficyCbList, notifyCb, tmp)
        {
            LL_DELETE(appHandle->noficyCbList, notifyCb);
            free(notifyCb);
        }
        appHandle->noficyCbList = NULL;

        /* If appHandle is singleton instance, reset the init info */
        if (appHandle == &appHandleInst)
        {
            appHandleInited = 0;
        }

        appHandleReleaseAudioTypeHash(appHandle);

        appHandleReleaseFeatureOptionsHash(appHandle);

        xmlCleanupParser();

        /* Flush app log */
        if (appLogFp)
        {
            fflush(appLogFp);
        }

        /* Unlock */
        appHandleUnlock(appHandle);

        return APP_NO_ERROR;
    }
}

EXPORT const char *appHandleGetBuildTimeStamp()
{
    return __DATE__" "__TIME__;
}

EXPORT int appHandleWriteLock(AppHandle *appHandle, const char *callerFun)
{
    int res = 0;

    if (!appHandle)
    {
        WARN_LOG("appHandle is NULL\n");
        return res;
    }

#ifndef WIN32
    while (1)
    {
        if (pthread_rwlock_trywrlock(&appHandle->lock) == 0)
        {
            appHandle->lockCallerFun = callerFun;
            DEBUG_LOG("AppHandle lock is locked by %s()\n", appHandle->lockCallerFun);
            break;
        }
        else
        {
            DEBUG_LOG("Cannot lock the AppHandle lock, delay some time. (the locker is %s())\n", appHandle->lockCallerFun);
            utilUsleep(1);
        }
    }
#else
    //DEBUG_LOG("Not support this function yet!\n");
#endif
    return res;
}

EXPORT int appHandleReadLock(AppHandle *appHandle, const char *callerFun)
{
    int res = 0;

    if (!appHandle)
    {
        WARN_LOG("appHandle is NULL\n");
        return res;
    }

#ifndef WIN32
    while (1)
    {
        if (pthread_rwlock_tryrdlock(&appHandle->lock) == 0)
        {
            appHandle->lockCallerFun = callerFun;
            DEBUG_LOG("AppHandle lock is locked by %s()\n", appHandle->lockCallerFun);
            break;
        }
        else
        {
            DEBUG_LOG("Cannot lock the AppHandle lock, delay some time. (the locker is %s())\n", appHandle->lockCallerFun);
            utilUsleep(1);
        }
    }
#else
    //DEBUG_LOG("Not support this function yet!\n");
#endif
    return res;
}

EXPORT int appHandleUnlock(AppHandle *appHandle)
{
    int res = 0;

    if (!appHandle)
    {
        WARN_LOG("appHandle is NULL\n");
        return res;
    }

#ifndef WIN32
    DEBUG_LOG("Unlock appHandle lock\n");
    res = pthread_rwlock_unlock(&appHandle->lock);
#endif
    return res;
}

EXPORT int appHandleInstWriteLock(const char *callerFun)
{
    int res = 0;

#ifndef WIN32
    while (1)
    {
        if (pthread_rwlock_trywrlock(&appHandleInstLock) == 0)
        {
            appHandleInstLockCallerFun = callerFun;
            DEBUG_LOG("%s acquired the appHandleInstLock\n", callerFun);
            break;
        }
        else
        {
            DEBUG_LOG("Cannot lock the appHandleInstLock, delay some time. (the locker is %s)\n", callerFun);
            utilUsleep(1);
        }
    }
#else
    //DEBUG_LOG("Not support this function yet!\n");
#endif
    return res;
}

EXPORT int appHandleInstUnlock()
{
    int res = 0;
#ifndef WIN32
    DEBUG_LOG("Unlock appHandleInst lock\n");
    res = pthread_rwlock_unlock(&appHandleInstLock);
#endif
    return res;
}

EXPORT FeatureOption *featureOptionCreate(const char *name, const char *value)
{
    FeatureOption *featureOption = malloc(sizeof(FeatureOption));
    featureOption->name = strdup(name);
    featureOption->value = strdup(value);
    return featureOption;
}

EXPORT void featureOptionRelease(FeatureOption *featureOption)
{
    free(featureOption->name);
    free(featureOption->value);
    free(featureOption);
}

EXPORT void appHandleReleaseFeatureOptionsHash(AppHandle *appHandle)
{
    if (appHandle->featureOptionsHash)
    {
        FeatureOption *tmp, *item;
        HASH_ITER(hh, appHandle->featureOptionsHash, item, tmp)
        {
            HASH_DEL(appHandle->featureOptionsHash, item);
            featureOptionRelease(item);
        }
    }
    appHandle->featureOptionsHash = NULL;
}

EXPORT AppHandle *appHandleGetInstance()
{
    appHandleInstWriteLock(__FUNCTION__);

    INFO_LOG("");

    if (!appHandleInited)
    {
        appHandleInit(&appHandleInst);
#ifdef WIN32
        appHandleParseXml(&appHandleInst, XML_FOLDER_ON_TUNING_TOOL, XML_CUS_FOLDER_ON_TUNING_TOOL);
#else
        appHandleParseXml(&appHandleInst, XML_FOLDER_ON_DEVICE, XML_CUS_FOLDER_ON_DEVICE);
#endif
        appHandleInited = 1;
    }

    appHandleInstUnlock();

    return &appHandleInst;
}

EXPORT APP_STATUS appHandleParseXml(AppHandle *appHandle, const char *dir, const char *cusDir)
{
    INFO_LOG("appHandle = 0x%p, dir = %s, cusDir = %s\n", appHandle, dir, cusDir);

    if (!appHandle)
    {
        ERR_LOG("appHandle is NULL!\n");
        return APP_ERROR;
    }

    if (!dir)
    {
        ERR_LOG("dir is NULL\n");
        return APP_ERROR;
    }

    if (appHandle->xmlDir || appHandle->xmlCusDir)
    {
        ERR_LOG("XML already parsed, don't call the appHandleParseXml twice!\n");
        return APP_ERROR;
    }

    appHandleWriteLock(appHandle, __FUNCTION__);

    appHandle->xmlDir = strdup(dir);
#if defined(APP_FORCE_ENABLE_CUS_XML) || defined(WIN32) || defined(CONFIG_MT_ENG_BUILD)
    appHandle->xmlCusDir = strdup(cusDir);
#else
#if !defined(WIN32)
    if (isCustXmlEnable())
    {
        appHandle->xmlCusDir = strdup(cusDir);
    }
    else
    {
        INFO_LOG("Cust XML folder not enabled");
    }
#endif
#endif
    INFO_LOG("XmlDir = %s, XmlCusDir = %s\n", appHandle->xmlDir, appHandle->xmlCusDir);

    /* Load feature options information */
    appHandleLoadDirFeatureOptionsInfo(appHandle);

    /* Load audio type information */
    appHandleLoadDirAudioTypeInfo(appHandle);

    appHandleUnlock(appHandle);

#ifndef WIN32
    /* Setup file system monitor thread */
    if (appHandle->xmlCusDir)
    {
        if (pthread_create(&appHandle->appThread, NULL, appHandleThreadLoop, (void *)appHandle))
        {
            ERR_LOG("Create app thread fail!\n");
            return APP_ERROR;
        }
        else
        {
            INFO_LOG("Create app thread successfully\n");
        }
    }
    else
    {
        WARN_LOG("Cus folder is NULL, don't create FS monitor thread\n");
    }
#endif
    return APP_NO_ERROR;
}

EXPORT APP_STATUS appHandleLoadDirFeatureOptionsInfo(AppHandle *appHandle)
{
    struct stat fileStat;
    int strLen;
    char *featureOptionsFile = NULL;
    xmlNode *node = NULL;
    xmlNode *root = NULL;
    xmlChar *name = NULL;
    xmlChar *value = NULL;

    if (!appHandle)
    {
        ERR_LOG("appHandle is NULL!\n");
        return APP_ERROR;
    }

    if (!appHandle->xmlDir)
    {
        ERR_LOG("xmlDir is NULL!\n");
        return APP_ERROR;
    }

    if (appHandle->featureOptionsHash)
    {
        WARN_LOG("Feature options already loaded, don't reload it!\n");
        return APP_NO_ERROR;
    }

    /* Check cus folder xml first */
    strLen = strlen(appHandle->xmlDir) + strlen(FEATURE_OPTIONS_XML) + 2;
    featureOptionsFile = (char *)malloc(strLen);
    sprintf(featureOptionsFile, "%s%s%s", appHandle->xmlDir, FOLDER, FEATURE_OPTIONS_XML);

    if (stat(featureOptionsFile, &fileStat) == -1)
    {
        ERR_LOG("No %s file\n", featureOptionsFile);
        free(featureOptionsFile);
        return APP_ERROR;
    }

    appHandle->featureOptionsDoc = xmlParseFile(featureOptionsFile);
    if (appHandle->featureOptionsDoc == NULL)
    {
        ERR_LOG("Failed to parse %s\n", featureOptionsFile);
        free(featureOptionsFile);
        return APP_ERROR;
    }
    else
    {
        INFO_LOG("Load xml file successfully. (%s)\n", featureOptionsFile);
    }
    free(featureOptionsFile);

    /* Parse informatino to feature options hash */
    root = xmlDocGetRootElement(appHandle->featureOptionsDoc);
    if (!root)
    {
        ERR_LOG("Root element is NULL\n");
        return APP_ERROR;
    }

    node = findXmlNodeByElemName(root, ELEM_AUDIO_FEATURE_OPTIONS);
    if (node && node->children)
    {
        node = node->children;
    }
    else
    {
        ERR_LOG("No feature options found!\n");
        return APP_ERROR;
    }

    while ((node = findXmlNodeByElemName(node->next, ELEM_PARAM)))
    {
        FeatureOption *featureOption;
        name = xmlGetProp(node, (const xmlChar *)ATTRI_NAME);
        value = xmlGetProp(node, (const xmlChar *)ATTRI_VALUE);

        featureOption = featureOptionCreate((const char *)name, (const char *)value);
        HASH_ADD_KEYPTR(hh, appHandle->featureOptionsHash, featureOption->name, strlen(featureOption->name), featureOption);

        if (name)
        {
            xmlFree(name);
        }

        if (value)
        {
            xmlFree(value);
        }
    }

    return APP_NO_ERROR;
}

EXPORT APP_STATUS appHandleLoadDirAudioTypeInfo(AppHandle *appHandle)
{
    size_t numOfAudioParamXml = 0;
    char audioType[MAX_AUDIO_TYPE_LEN];

#ifdef __linux__
    struct dirent **namelist;
    int i;
    int total;

    if (!appHandle)
    {
        ERR_LOG("appHandle is NULL!\n");
        return APP_ERROR;
    }

    total = scandir(appHandle->xmlDir, &namelist, 0, alphasort);

    /* Release old audio type first */
    appHandleReleaseAudioTypeHash(appHandle);

    if (total < 0)
    {
        ERR_LOG("Scandir error\n");
    }
    else
    {
        for (i = 0; i < total; i++)
        {
            if (strstr(namelist[i]->d_name, AUDIO_PARAM_XML_POSFIX) == NULL)
            {
                DEBUG_LOG("File name's posfix is not AudioParam.xml (%s)\n", namelist[i]->d_name);
                continue;
            }

            sscanf(namelist[i]->d_name, AUDIO_TYPE_FMT_STR(MAX_AUDIO_TYPE_LEN), audioType);
            if (appHandleIsValidAudioType(appHandle, audioType))
            {
                appHandleAddAudioType(appHandle, audioType);
            }
            else
            {
                WARN_LOG("Invalid audio param xml = %s\n", namelist[i]->d_name);
            }
        }
    }
#else
    WIN32_FIND_DATA FindFileData;
    HANDLE hFind;
    UT_string *path = NULL;

    if (!appHandle)
    {
        ERR_LOG("appHandle is NULL!\n");
        return APP_ERROR;
    }

    /* Release old audio type first */
    appHandleReleaseAudioTypeHash(appHandle);

    /* Check preload xml folder */
    utstring_new(path);
    utstring_printf(path, "%s"FOLDER"*"AUDIO_PARAM_XML_POSFIX, appHandle->xmlDir);
    hFind = FindFirstFile(utstring_body(path), &FindFileData);
    utstring_free(path);

    if (hFind == INVALID_HANDLE_VALUE)
    {
        WARN_LOG("No xml found!\n");
        return APP_ERROR;
    }

    do
    {
        sscanf(FindFileData.cFileName, AUDIO_TYPE_FMT_STR(MAX_AUDIO_TYPE_LEN), audioType);

        if (appHandleIsValidAudioType(appHandle, audioType))
        {
            appHandleAddAudioType(appHandle, audioType);
        }
        else
        {
            INFO_LOG("Invalid audio param xml = %s\n", FindFileData.cFileName);
        }
    }
    while (FindNextFile(hFind, &FindFileData));
#endif

    /* Load all XMLs */
    appHandleLoadAllAudioTypeXml(appHandle);
    INFO_LOG("Load all audio type XML - ok\n");

    /* Modify data depends on feature options */
    appHandleReviseXmlDocByFeatureOptions(appHandle);

    /* Load hash info from XML */
    appHandleLoadAllAudioTypeHash(appHandle);
    INFO_LOG("Load all audio Hash - ok\n");

    if (appDebugLevel == DEBUG_LEVEL)
    {
        appHandleDumpAudioTypeList(appHandle);
    }

    return APP_NO_ERROR;
}

EXPORT size_t appHandleGetNumOfAudioType(AppHandle *appHandle)
{
    if (!appHandle)
    {
        ERR_LOG("appHandle is NULL!\n");
        return APP_ERROR;
    }

    return HASH_COUNT(appHandle->audioTypeHash);
}

EXPORT APP_STATUS appHandleLoadAllAudioTypeXml(AppHandle *appHandle)
{
    size_t i;
    size_t count = appHandleGetNumOfAudioType(appHandle);

    for (i = 0; i < count; i++)
    {
        AudioType *audioType = appHandleGetAudioTypeByIndex(appHandle, i);

        /* Load xml struct */
        if (appHandleLoadAudioTypeXml(appHandle, audioType) == APP_ERROR)
        {
            WARN_LOG("Load audio type XML failed. (%s)\n", audioType->name);
        }
    }

    return APP_NO_ERROR;
}

EXPORT APP_STATUS appHandleLoadAudioTypeXml(AppHandle *appHandle, AudioType *audioType)
{
    char *audioTypeFile;

    INFO_LOG("audioType = %s\n", audioType->name);

    // Load AudioParamXml
    audioTypeFile = appHandleGetAudioTypeFilePath(appHandle, audioType->name, AUDIO_PARAM_XML_POSFIX);
    if (audioTypeFile == NULL)
    {
        WARN_LOG("The AudioTypeFile(%s%s) doesn't exist.\n", audioType->name, AUDIO_PARAM_XML_POSFIX);
        return APP_ERROR;
    }

    audioType->audioParamDoc = xmlParseFile(audioTypeFile);

    if (audioType->audioParamDoc == NULL)
    {
        ERR_LOG("Failed to parse %s\n", audioTypeFile);
        free(audioTypeFile);

        // Audio param file broken, load preload xml file instead
        audioTypeFile = appHandleGetPreloadAudioTypeFilePath(appHandle, audioType->name, AUDIO_PARAM_XML_POSFIX);
        if (audioTypeFile == NULL)
        {
            WARN_LOG("The AudioTypeFile(%s%s) doesn't exist.\n", audioType->name, AUDIO_PARAM_XML_POSFIX);
            return APP_ERROR;
        }

        WARN_LOG("Trying to load preload %s file instead of broken XML file!\n", audioTypeFile);
        audioType->audioParamDoc = xmlParseFile(audioTypeFile);
        if (audioType->audioParamDoc == NULL)
        {
            ERR_LOG("Failed to parse %s\n", audioTypeFile);
            free(audioTypeFile);
            return APP_ERROR;
        }
        else
        {
            INFO_LOG("Load xml file successfully. (%s)\n", audioTypeFile);
        }
    }
    else
    {
        INFO_LOG("Load xml file successfully. (%s)\n", audioTypeFile);
    }

    free(audioTypeFile);

    // Load ParamUnitDescXml
    audioTypeFile = appHandleGetAudioTypeFilePath(appHandle, audioType->name, PARAM_UNIT_DESC_XML_POSFIX);
    if (audioTypeFile == NULL)
    {
        WARN_LOG("The AudioTypeFile(%s%s) doesn't exist.\n", audioType->name, PARAM_UNIT_DESC_XML_POSFIX);
        return APP_ERROR;
    }

    audioType->paramUnitDescDoc = xmlParseFile(audioTypeFile);
    if (audioType->paramUnitDescDoc == NULL)
    {
        ERR_LOG("Failed to parse %s%s\n", audioTypeFile, PARAM_UNIT_DESC_XML_POSFIX);
        free(audioTypeFile);
        return APP_ERROR;
    }
    else
    {
        INFO_LOG("Load xml file successfully. (%s)\n", audioTypeFile);
    }
    free(audioTypeFile);

#ifdef WIN32
    // Load ParamTreeViewXml only for tuning tool
    audioTypeFile = appHandleGetAudioTypeFilePath(appHandle, audioType->name, PARAM_TREE_VIEW_XML_POSFIX);
    if (audioTypeFile == NULL)
    {
        INFO_LOG("The AudioTypeFile(%s%s) doesn't exist.\n", audioType->name, PARAM_TREE_VIEW_XML_POSFIX);
        free(audioTypeFile);
    }
    else
    {
        audioType->paramTreeViewDoc = xmlParseFile(audioTypeFile);
        if (audioType->audioParamDoc == NULL)
        {
            DEBUG_LOG("Failed to parse %s%s\n", audioTypeFile, PARAM_TREE_VIEW_XML_POSFIX);
        }
        else
        {
            INFO_LOG("Load xml file successfully. (%s)\n", audioTypeFile);
        }
        free(audioTypeFile);
    }
#endif

    /* Get tab name info */
    audioTypeParseTabName(audioType);

    /* Get version info */
    if (audioTypeParseXmlVer(audioType) == APP_ERROR)
    {
        ERR_LOG("Cannot parse xml version info. (%s)\n", audioType->name);
        return APP_ERROR;
    }

#ifndef WIN32
    /* XML Version check for device driver or HAL */
    if (!audioTypeIsDeviceSupportedXmlVer(audioType))
    {
        abort();
    }
#endif

    return APP_NO_ERROR;
}

EXPORT char *appHandleGetAudioTypeFilePath(AppHandle *appHandle, const char *audioType, const char *posfix)
{
    /* Check cus folder xml first */
    struct stat fileStat;
    int strLen;
    char *path;

    if (appHandle->xmlCusDir && !strcmp(posfix, AUDIO_PARAM_XML_POSFIX))
    {
        strLen = strlen(appHandle->xmlCusDir) + strlen(audioType) + strlen(posfix) + 2;
        path = (char *)malloc(strLen);
        sprintf(path, "%s%s%s%s", appHandle->xmlCusDir, FOLDER, audioType, posfix);

        if (stat(path, &fileStat) != -1)
        {
            return path;
        }
        else
        {
            free(path);
        }
    }

    /* Check default folder */
    strLen = strlen(appHandle->xmlDir) + strlen(audioType) + strlen(posfix) + 2;
    path = (char *)malloc(strLen);
    sprintf(path, "%s%s%s%s", appHandle->xmlDir, FOLDER, audioType, posfix);

    if (stat(path, &fileStat) != -1)
    {
        return path;
    }

    free(path);
    return NULL;
}

EXPORT char *appHandleGetPreloadAudioTypeFilePath(AppHandle *appHandle, const char *audioType, const char *posfix)
{
    /* Check cus folder xml first */
    struct stat fileStat;
    int strLen;
    char *path;

    /* Check default folder */
    strLen = strlen(appHandle->xmlDir) + strlen(audioType) + strlen(posfix) + 2;
    path = (char *)malloc(strLen);
    sprintf(path, "%s%s%s%s", appHandle->xmlDir, FOLDER, audioType, posfix);

    if (stat(path, &fileStat) != -1)
    {
        return path;
    }

    free(path);
    return NULL;
}

EXPORT int appHandleIsValidAudioType(AppHandle *appHandle, const char *audioType)
{
    char *filePath;

    assert(appHandle != NULL);
    filePath = appHandleGetAudioTypeFilePath(appHandle, audioType, PARAM_UNIT_DESC_XML_POSFIX);
    if (filePath == NULL)
    {
        ERR_LOG("%s audio type is not valid! (%s is not exist)\n", audioType, filePath);
        free(filePath);
        return 0;
    }

    free(filePath);
    return 1;
}

EXPORT AudioType *appHandleAddAudioType(AppHandle *appHandle, const char *audioTypeName)
{
    AudioType *audioType;

    if (!appHandle)
    {
        ERR_LOG("The appHandle is NULL\n");
        return NULL;
    }

    if (!audioTypeName)
    {
        ERR_LOG("The audioTypeName is NULL\n");
        return NULL;
    }

    audioType = audioTypeCreate(appHandle, audioTypeName);

    /* Add audio type to hash */
    HASH_ADD_KEYPTR(hh, appHandle->audioTypeHash, audioType->name, strlen(audioType->name), audioType);

    return audioType;
}

EXPORT AudioType *appHandleGetAudioTypeByIndex(AppHandle *appHandle, size_t index)
{
    AudioType *audioType = NULL;
    size_t i = 0;

    DEBUG_LOG("appHandle = 0x%p, index = %lu\n", appHandle, index);

    if (!appHandle)
    {
        ERR_LOG("appHandle is NULL!\n");
        return NULL;
    }

    for (audioType = appHandle->audioTypeHash; audioType ; audioType = audioType->hh.next)
    {
        if (index == i++)
        {
            return audioType;
        }
    }

    return NULL;
}

EXPORT AudioType *appHandleGetAudioTypeByName(AppHandle *appHandle, const char *name)
{
    AudioType *audioType = NULL;

    INFO_LOG("appHandle = 0x%p, name = %s\n", appHandle, name);

    if (!appHandle)
    {
        ERR_LOG("appHandle is NULL!\n");
        return NULL;
    }

    HASH_FIND_STR(appHandle->audioTypeHash, name, audioType);

    return audioType;
}

EXPORT void appHandleReleaseAudioTypeHash(AppHandle *appHandle)
{
    if (appHandle->audioTypeHash)
    {
        AudioType *tmp, *item;
        HASH_ITER(hh, appHandle->audioTypeHash, item, tmp)
        {
            HASH_DEL(appHandle->audioTypeHash, item);
            audioTypeRelease(item);
        }
    }
    appHandle->audioTypeHash = NULL;
}

EXPORT void appHandleDumpAudioTypeList(AppHandle *appHandle)
{
    size_t index = 0;
    size_t numOfAudioType = appHandleGetNumOfAudioType(appHandle);
    INFO_LOG("=================================\n");
    INFO_LOG("Totoal num of Audio Type List = %lu\n", numOfAudioType);
    for (index = 0; index < numOfAudioType; index++)
    {
        AudioType *audioType = appHandleGetAudioTypeByIndex(appHandle, index);
        INFO_LOG("AudioType[%lu] = %s\n", index, audioType->name);
        audioTypeDump(audioType);
    }
}

EXPORT APP_STATUS appHandleLoadAllAudioTypeHash(AppHandle *appHandle)
{
    size_t index = 0;
    size_t numOfAudioType = appHandleGetNumOfAudioType(appHandle);
    /* Load stage1 information */
    for (index = 0; index < numOfAudioType; index++)
    {
        AudioType *audioType = appHandleGetAudioTypeByIndex(appHandle, index);
        audioTypeLoadStage1Hash(audioType);
    }

    /* Load stage2 information (ex: ParamTreeView's switch object)*/
    for (index = 0; index < numOfAudioType; index++)
    {
        AudioType *audioType = appHandleGetAudioTypeByIndex(appHandle, index);
        audioTypeLoadStage2Hash(audioType);
    }

    return APP_NO_ERROR;
}

EXPORT void appHandleRegXmlChangedCb(AppHandle *appHandle, NOTIFY_CB_FUN callbackFun)
{
    INFO_LOG("appHandle = 0x%p, callbackFun = 0x%p\n", appHandle, callbackFun);

    appHandleWriteLock(appHandle, __FUNCTION__);

    if (appHandle && callbackFun)
    {
        /* Checking the duplicated callback function registration */
        NotifyCb *notifyCb;
        LL_FOREACH(appHandle->noficyCbList, notifyCb)
        {
            if (notifyCb->cb == callbackFun)
            {
                INFO_LOG("Same callback function found. ignore it\n");
                appHandleUnlock(appHandle);
                return;
            }
        }

        notifyCb = malloc(sizeof(NotifyCb));
        notifyCb->cb = callbackFun;
        LL_APPEND(appHandle->noficyCbList, notifyCb);
    }
    else
    {
        WARN_LOG("Cannot register xml callback! (AppHandle = 0x%p, callbackFun = 0x%p)\n", appHandle, callbackFun);
    }

    appHandleUnlock(appHandle);
}

EXPORT void appHandleUnregXmlChangedCb(AppHandle *appHandle, NOTIFY_CB_FUN callbackFun)
{
    INFO_LOG("appHandle = 0x%p, callbackFun = 0x%p\n", appHandle, callbackFun);

    appHandleWriteLock(appHandle, __FUNCTION__);

    if (appHandle && callbackFun)
    {
        NotifyCb *notifyCb, *tmp;
        LL_FOREACH_SAFE(appHandle->noficyCbList, notifyCb, tmp)
        {
            if (notifyCb->cb == callbackFun)
            {
                LL_DELETE(appHandle->noficyCbList, notifyCb);
                free(notifyCb);
                INFO_LOG("Callback function unregistered. (0x%p, 0x%p)\n", callbackFun, callbackFun);
                break;
            }
        }
    }
    else
    {
        WARN_LOG("Cannot unregister xml callback! (AppHandle = 0x%p, callbackFun = %p)\n", appHandle, callbackFun);
    }

    appHandleUnlock(appHandle);
}

EXPORT void *appHandleThreadLoop(void *arg)
{
#if defined(WIN32)
    /* Always disable on WIN32 */
    return NULL;
#else
    /* This thread only work on linux platform */
    /* Only eng load could monitor custom folder */
    AppHandle *appHandle = (AppHandle *)arg;
    ssize_t len;
    char buf[INOTIFY_BUF_SIZE];
    char *ptr;
    const struct inotify_event *event;

#if !defined(APP_FORCE_ENABLE_CUS_XML) && !defined(CONFIG_MT_ENG_BUILD)
    /* User load, check NVRam status */
    if (isCustXmlEnable())
    {
        INFO_LOG("User load, cust xml enabled\n");
    }
    else
    {
        INFO_LOG("User load but cust xml disabled\n");
        return NULL;
    }
#endif

    if (!appHandle->xmlCusDir)
    {
        WARN_LOG("xmlCusDir is NULL, don't run the appHandleThreadLoop !!!");
        exit(1);
    }

    /* Create folder first to make inotify work */
    utilMkdir(appHandle->xmlCusDir);

    /* Register signal handler */
    struct sigaction sa;
    sa.sa_handler = NULL;
    sa.sa_sigaction = &signalHandler;
    sa.sa_flags = SA_SIGINFO;
    sigemptyset(&sa.sa_mask);

    if (sigaction(SIGUSR1, &sa, NULL) < 0)
    {
        ERR_LOG("sigaction fail");
        exit(1);
    }

    /* inotify registration */
    appHandle->inotifyFd = inotify_init();
    if (appHandle->inotifyFd < 0)
    {
        ERR_LOG("inotify_init failed !!!");
        exit(1);
    }

    INFO_LOG("Add inotify monitor path = %s, fd = %d\n", appHandle->xmlCusDir, appHandle->inotifyFd);

    while (1)
    {
        if (inotify_add_watch(appHandle->inotifyFd, appHandle->xmlCusDir, IN_CLOSE_WRITE) < 0)
        {
            ERR_LOG("inotify_add_watch failed !!! try again...");
            utilMkdir(appHandle->xmlCusDir);
            utilUsleep(1000000);
        } else {
            break;
        }
    }

    while (!appHandle->appThreadExit)
    {
        INFO_LOG("inotify read waiting... (fd = %d)\n", appHandle->inotifyFd);
        len = read(appHandle->inotifyFd, buf, sizeof(buf));

        if (len < 0)
        {
            if (appHandle->appThreadExit)
            {
                break;
            }

            ERR_LOG("inotify read error!\n");
            pthread_exit(NULL);
        }

        /* Loop over all events in the buffer */
        for (ptr = buf; ptr < buf + len; ptr += sizeof(struct inotify_event) + event->len)
        {
            event = (const struct inotify_event *) ptr;
            if (event->len)
            {
                NotifyCb *notifyCb;
                char audioTypeName[MAX_AUDIO_TYPE_LEN];
                AudioType *audioType;

                if (strstr(event->name, AUDIO_PARAM_XML_POSFIX) == NULL)
                {
                    INFO_LOG("File name's posfix is not AudioParam.xml (%s)\n", event->name);
                    continue;
                }

                sscanf(event->name, AUDIO_TYPE_FMT_STR(MAX_AUDIO_TYPE_LEN), audioTypeName);
                INFO_LOG("XML File chanegd (%s)\n", event->name);

                audioType = appHandleGetAudioTypeByName(appHandle, audioTypeName);
                if (audioType)
                {
                    audioType->allowReload = 1;
                }

                /* notify users */
                INFO_LOG("Notify all callback function.\n");
                LL_FOREACH(appHandle->noficyCbList, notifyCb)
                {
                    INFO_LOG("Notify callback function. (0x%p, %pf)\n", notifyCb->cb, notifyCb->cb);
                    (*notifyCb->cb)(appHandle, audioTypeName);
                }
            }
        }
    }

    inotify_rm_watch(appHandle->inotifyFd, IN_CLOSE_NOWRITE);

    if (appHandle->inotifyFd)
    {
        INFO_LOG("close inotify handle %d\n", appHandle->inotifyFd);
        close(appHandle->inotifyFd);
    }

    INFO_LOG("appHandleThreadLoop exit\n");
    return NULL;
#endif
}

EXPORT APP_STATUS appHandleReloadAudioType(AppHandle *appHandle, const char *audioTypeName)
{
    /* Release old audioType */
    char *audioTypeFile;
    AudioType *audioType;

    INFO_LOG("appHandle = 0x%p, audioTypeName = %s\n", appHandle, audioTypeName);

    audioType = appHandleGetAudioTypeByName(appHandle, audioTypeName);
    if (!audioType)
    {
        ERR_LOG("Invalid AudioType name = %s\n", audioTypeName);
        return APP_ERROR;
    }

    /* Write lock */
    audioTypeWriteLock(audioType, __FUNCTION__);

    /* Checking if the audioType reloaded */
    if (!audioType->allowReload)
    {
        INFO_LOG("AudioType is already reloaded!\n");
        audioTypeUnlock(audioType);
        return APP_NO_ERROR;
    }

    /* Release audio param data */
    audioTypeReleaseAudioParam(audioType);
    /* Release audio param xml */
    if (audioType->audioParamDoc)
    {
        xmlFreeDoc(audioType->audioParamDoc);
    }

    /* Load AudioParam XML */
    audioTypeFile = appHandleGetAudioTypeFilePath(appHandle, audioType->name, AUDIO_PARAM_XML_POSFIX);
    if (audioTypeFile == NULL)
    {
        WARN_LOG("The AudioTypeFile(%s%s) doesn't exist.\n", audioType->name, AUDIO_PARAM_XML_POSFIX);
        audioTypeUnlock(audioType);
        return APP_ERROR;
    }

    audioType->audioParamDoc = xmlParseFile(audioTypeFile);
    if (audioType->audioParamDoc == NULL)
    {
        ERR_LOG("Failed to parse %s\n", audioTypeFile);
        free(audioTypeFile);
        audioTypeUnlock(audioType);
        return APP_ERROR;
    }
    else
    {
        INFO_LOG("Load xml file successfully. (%s)\n", audioTypeFile);
    }

    free(audioTypeFile);

    /* Load AudioParam hash */
    if (audioTypeLoadParamUnitHash(audioType) == APP_ERROR)
    {
        audioTypeUnlock(audioType);
        return APP_ERROR;
    }

    if (audioTypeLoadParamTreeHash(audioType) == APP_ERROR)
    {
        audioTypeUnlock(audioType);
        return APP_ERROR;
    }

    /* AudioType reloaded */
    audioType->allowReload = 0;

    audioTypeUnlock(audioType);
    return APP_NO_ERROR;
}

EXPORT const char *appHandleGetFeatureOptionValue(AppHandle *appHandle, const char *featureOptionName)
{
    FeatureOption *featureOption = NULL;

    if (!appHandle)
    {
        ERR_LOG("appHandle is NULL\n");
        return NULL;
    }

    if (!featureOptionName)
    {
        DEBUG_LOG("featureOptionName is NULL\n");
        return NULL;
    }

    HASH_FIND_STR(appHandle->featureOptionsHash, featureOptionName, featureOption);
    if (featureOption)
    {
        return featureOption->value;
    }

    return NULL;
}

EXPORT int appHandleIsFeatureOptionEnabled(AppHandle *appHandle, const char *featureOptionName)
{
    const char *featureOptionValueStr;
    if (!appHandle)
    {
        WARN_LOG("appHandle is NULL\n");
        return 0;
    }

    if (!featureOptionName)
    {
        WARN_LOG("featureOptionName is NULL\n");
        return 0;
    }

    featureOptionValueStr = appHandleGetFeatureOptionValue(appHandle, featureOptionName);
    if (featureOptionValueStr)
    {
        return !strcmp(featureOptionValueStr, "yes");
    }
    else
    {
        DEBUG_LOG("No %s such feature option\n", featureOptionName);
        return 0;
    }
}

EXPORT size_t appHandleGetNumOfFeatureOption(AppHandle *appHandle)
{
    if (!appHandle)
    {
        ERR_LOG("appHandle is NULL!\n");
        return APP_ERROR;
    }

    return HASH_COUNT(appHandle->featureOptionsHash);
}

EXPORT FeatureOption *appHandleGetFeatureOptionByIndex(AppHandle *appHandle, size_t index)
{
    FeatureOption *featureOption = NULL;
    size_t i = 0;

    if (!appHandle)
    {
        ERR_LOG("appHandle is NULL\n");
        return NULL;
    }

    for (featureOption = appHandle->featureOptionsHash; featureOption ; featureOption = featureOption->hh.next)
    {
        if (index == i++)
        {
            return featureOption;
        }
    }

    return NULL;
}

/* This function is only work for windows */
EXPORT void appHandleRedirectIOToConsole()
{
    INFO_LOG("");
#ifdef WIN32
    outputLogToStdout = 1;
    redirectIOToConsole();
#endif
}

int removeNodeByFeatureOption(AppHandle *appHandle, xmlNode *categoryNode)
{
    /* Process Category of CategoryTpe Node */
    xmlChar *featureOption = xmlNodeGetProp(categoryNode, ATTRI_FEATURE_OPTION);
    if (featureOption)
    {
        int Not = 0;
        if (featureOption[0] == '!')
        {
            Not = 1;
            featureOption++;
        }

        if (!(Not ^ appHandleIsFeatureOptionEnabled(appHandle, (char *)featureOption)))
        {
            xmlNode *deleteNode = categoryNode;
            categoryNode = categoryNode->next;

            INFO_LOG("Remove %s category (%s feature option is disabled)\n", xmlNodeGetProp(deleteNode, ATTRI_NAME), featureOption);
            xmlUnlinkNode(deleteNode);
            xmlFreeNode(deleteNode);
            return 1;
        }
    }

    return 0;
}

EXPORT void appHandleReviseXmlDocByFeatureOptions(AppHandle *appHandle)
{
    // Travel all audioType's category & category group node
    size_t i;
    size_t numOfAppHandle = appHandleGetNumOfAudioType(appHandle);
    for (i = 0; i < numOfAppHandle; i++)
    {
        xmlNode *categoryTypeListNode, *categoryTypeNode, *categoryGroupNode, *categoryNode, *prevCategoryGroupNode, *prevCategoryNode, *prevCategoryTypeNode;
        AudioType *audioType = appHandleGetAudioTypeByIndex(appHandle, i);
        categoryTypeListNode = audioTypeGetCategoryTypeListNode(audioType);
        if (!categoryTypeListNode)
        {
            continue;
        }

        categoryTypeNode = categoryTypeListNode->children;
        while ((categoryTypeNode = findXmlNodeByElemName(categoryTypeNode->next, ELEM_CATEGORY_TYPE)))
        {
            prevCategoryTypeNode = categoryTypeNode->prev;
            if (removeNodeByFeatureOption(appHandle, categoryTypeNode))
            {
                categoryTypeNode = prevCategoryTypeNode;
                continue;
            }

            /* Process CategoryType node */
            categoryGroupNode = categoryTypeNode->children;
            while ((categoryGroupNode = findXmlNodeByElemName(categoryGroupNode->next, ELEM_CATEGORY_GROUP)))
            {
                /* Process CategoryGroup of CategoryType Node */
                prevCategoryGroupNode = categoryGroupNode->prev;
                if (removeNodeByFeatureOption(appHandle, categoryGroupNode))
                {
                    categoryGroupNode = prevCategoryGroupNode;
                    continue;
                }

                categoryNode = categoryGroupNode->children;
                while ((categoryNode = findXmlNodeByElemName(categoryNode->next, ELEM_CATEGORY)))
                {
                    /* Process Category of CategoryGroup Node */
                    prevCategoryNode = categoryNode->prev;
                    if (removeNodeByFeatureOption(appHandle, categoryNode))
                    {
                        categoryNode = prevCategoryNode;
                    }
                }
            }

            categoryNode = categoryTypeNode->children;
            while ((categoryNode = findXmlNodeByElemName(categoryNode->next, ELEM_CATEGORY)))
            {
                prevCategoryNode = categoryNode->prev;
                if (removeNodeByFeatureOption(appHandle, categoryNode))
                {
                    categoryNode = prevCategoryNode;
                }
            }
        }
    }
}

EXPORT APP_STATUS appHandleCompressFiles(const char* srcDir, const char* destFile)
{
#ifdef WIN32
    INFO_LOG("%s(), src = %s, dest = %s\n", __FUNCTION__, srcDir, destFile);
    if (!srcDir || !destFile)
    {
        ERR_LOG("%s(), srcDir or destFile is NULL\n", __FUNCTION__);
        return APP_ERROR;
    } else {
        UT_string *path = NULL;
        utstring_new(path);
        utstring_printf(path, "a -tzip %s %s\\*", destFile, srcDir);
        utilShellExecute("7za.exe", utstring_body(path));
        utstring_free(path);
    }
#else
    ERR_LOG("Not support on linux\n");
#endif
    return APP_NO_ERROR;
}

EXPORT APP_STATUS appHandleUncompressFile(const char* srcFile, const char* destDir)
{
#ifdef WIN32
    INFO_LOG("%s(), src = %s, dest = %s\n", __FUNCTION__, srcFile, destDir);
    if (!srcFile || !destDir)
    {
        ERR_LOG("%s(), srcFile or destDir is NULL\n", __FUNCTION__);
        return APP_ERROR;
    } else {
        UT_string *path = NULL;
        utstring_new(path);
        utstring_printf(path, "x %s -y -o%s\\", srcFile, destDir);
        utilShellExecute("7za.exe", utstring_body(path));
        utstring_free(path);
    }
#else
    ERR_LOG("Not support on linux\n");
#endif
    return APP_NO_ERROR;
}

EXPORT APP_STATUS appHandleGetAudioTypeSupportedVerInfo(const char* audioTypeName, int* paramUnitDescVerMaj, int* paramUnitDescVerMin, int* audioParamVerMaj, int* audioParamVerMin)
{
    int i = 0;
    while(audioTypeSupportVerInfo[i].audioTypeName != NULL)
    {
        if (!strcmp(audioTypeName, audioTypeSupportVerInfo[i].audioTypeName))
        {
            *paramUnitDescVerMaj = audioTypeSupportVerInfo[i].paramUnitDescVerMaj;
            *paramUnitDescVerMin = audioTypeSupportVerInfo[i].paramUnitDescVerMin;
            *audioParamVerMaj = audioTypeSupportVerInfo[i].audioParamVerMaj;
            *audioParamVerMin = audioTypeSupportVerInfo[i].audioParamVerMin;
            return APP_NO_ERROR;
        }
        i++;
    }

    ERR_LOG("%s AudioType version support info not found!\n", audioTypeName);
    return APP_ERROR;
}

EXPORT void appHandleShowAudioTypeSupportedVerInfo(AppHandle* appHandle)
{
    int i = 0;
    INFO_LOG("=======================\n");
    while(audioTypeSupportVerInfo[i].audioTypeName != NULL)
    {
        INFO_LOG("[%d] %s, ParamUnitDesc ver(%d.%d), AudioParam ver(%d.%d)\n",
            i,
            audioTypeSupportVerInfo[i].audioTypeName, audioTypeSupportVerInfo[i].paramUnitDescVerMaj,
            audioTypeSupportVerInfo[i].paramUnitDescVerMin, audioTypeSupportVerInfo[i].audioParamVerMaj, audioTypeSupportVerInfo[i].audioParamVerMin);
        i++;
    }
}
