/* =========================================================================

DESCRIPTION
   Netease && Xunfei speech processing main program
   Cae voice process

Copyright (c) 2017 by Netease, Co,LTD.  All Rights Reserved.
============================================================================ */

/* =========================================================================

                             REVISION

when                       who why
--------                    ---------
-------------------------------------------
2017/06/28          wangzijiao                                  Created.
============================================================================ */

/* ------------------------------------------------------------------------
** Includes
** ------------------------------------------------------------------------ */
#include "cae_lib.h"
#include "error.h"
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "cae.h"
#include <cae/cae_errors.h>

#define Link_Hidden

/* ------------------------------------------------------------------------
** Macros
** ------------------------------------------------------------------------ */

/* ------------------------------------------------------------------------
** Defines
** ------------------------------------------------------------------------ */

/* ------------------------------------------------------------------------
** Types
** ------------------------------------------------------------------------ */

/* ------------------------------------------------------------------------
** Global Variable Definitions
** ------------------------------------------------------------------------ */
#ifndef Link_Hidden
static Proc_CAENew api_cae_new;
static Proc_CAEAudioWrite api_cae_audio_write;
static Proc_CAEResetEng api_cae_reset_eng;
static Proc_CAESetRealBeam api_cae_set_real_beam;
static Proc_CAESetWParam api_cae_set_wparam;
static Proc_CAEGetWParam api_cae_get_wparam;
static Proc_CAEGetVersion api_cae_get_version;
static Proc_CAEGetChannel api_cae_get_channel;
static Proc_CAESetShowLog api_cae_set_show_log;
static Proc_CAEDestroy api_cae_destroy;
#else

#endif
/* ------------------------------------------------------------------------
** Function Definitions
** ------------------------------------------------------------------------ */

int Netease_CaeInit(CAEDATA **caedata, cae_ivw_fn ivwCb, cae_audio_fn audioCb) {
    int ret = NETEASE_SUCCESS;
    const char *caeResPath = "/usr/share/netease/ivw_resource.jet";

#ifndef Link_Hidden
    const char *libname = "/usr/lib/libcae.so";
    void *hInstance = cae_LoadLibrary(libname);
    n_debug("Load path: %s\n", libname);
    if (hInstance == NULL) {
        n_error("Can not open library! errno:%d\n", errno);
        perror("open cae lib(/usr/lib/libcae.so)!");
        return NETEASE_ERROR_OPEN_FILE;
    } else {
        n_debug("open library successfully!\n");
    }

    api_cae_new = (Proc_CAENew)cae_GetProcAddress(hInstance, "CAENew");
    api_cae_audio_write =
        (Proc_CAEAudioWrite)cae_GetProcAddress(hInstance, "CAEAudioWrite");
    api_cae_reset_eng =
        (Proc_CAEResetEng)cae_GetProcAddress(hInstance, "CAEResetEng");
    api_cae_set_real_beam =
        (Proc_CAESetRealBeam)cae_GetProcAddress(hInstance, "CAESetRealBeam");
    api_cae_set_wparam =
        (Proc_CAESetWParam)cae_GetProcAddress(hInstance, "CAESetWParam");
    api_cae_get_wparam =
        (Proc_CAEGetWParam)cae_GetProcAddress(hInstance, "CAEGetWParam");
    api_cae_get_version =
        (Proc_CAEGetVersion)cae_GetProcAddress(hInstance, "CAEGetVersion");
    api_cae_get_channel =
        (Proc_CAEGetChannel)cae_GetProcAddress(hInstance, "CAEGetChannel");
    api_cae_destroy =
        (Proc_CAEDestroy)cae_GetProcAddress(hInstance, "CAEDestroy");
    api_cae_set_show_log =
        (Proc_CAESetShowLog)cae_GetProcAddress(hInstance, "CAESetShowLog");

    *caedata = (CAEDATA *)malloc(sizeof(CAEDATA));
    if (NULL == *caedata) {
        n_error("caeData malloc fail!\n");
        return NETEASE_ERROR_FAIL;
    }
    ret = api_cae_new(&(*caedata)->cae, caeResPath, ivwCb, NULL, audioCb, NULL,
                      *caedata);

    if (MSP_SUCCESS != ret) {
        n_error("Load cae library failed:%d\n", ret);
        free(*caedata);
        *caedata = NULL;
        return MSP_ERROR_FAIL;
    }
    n_debug("Cae version(not hidden):%s\n", api_cae_get_version());
    api_cae_set_show_log(0);
#else
    *caedata = (CAEDATA *)malloc(sizeof(CAEDATA));
    if (NULL == *caedata) {
        n_error("caeData malloc fail!\n");
        return NETEASE_ERROR_FAIL;
    }

    ret = CAENew(&(*caedata)->cae, caeResPath, ivwCb, NULL, audioCb, NULL,
                 *caedata);
    if (MSP_SUCCESS != ret) {
        n_error("Load cae library failed:%d\n", ret);
        free(*caedata);
        *caedata = NULL;
        return MSP_ERROR_FAIL;
    }
    n_debug("Cae version(hidden link):%s\n", CAEGetVersion());
#endif

    return NETEASE_SUCCESS;
}

void Netease_CAEDestroy(CAE_HANDLE *caeData) {
    CAE_HANDLE tmp = *caeData;
#ifndef Link_Hidden
    api_cae_destroy(tmp);
#else
    CAEDestroy(tmp);
#endif
    free(tmp);
    tmp = NULL;
    //caeData = NULL;
}

int Netease_CAEAudioWrite(CAEDATA *cae, const void *audioData,
                          unsigned int audioLen) {
#ifndef Link_Hidden
    return api_cae_audio_write(cae->cae, audioData, audioLen);
#else
    return CAEAudioWrite(cae->cae, audioData, audioLen);
#endif
}

int Netease_CAEResetEng(CAEDATA *cae) {
#ifndef Link_Hidden
    return api_cae_reset_eng(cae->cae);
#else
    return CAEResetEng(cae->cae);
#endif
}

int Netease_CAESetRealBeam(CAEDATA *cae, int beam) {
#ifndef Link_Hidden
    return api_cae_set_real_beam(cae->cae, beam);
#else
    return CAESetRealBeam(cae->cae, beam);
#endif
}

int Netease_CAESetWParam(CAEDATA *cae, const char *param, const char *value) {
#ifndef Link_Hidden
    return api_cae_set_wparam(cae->cae, param, value);
#else
    return CAESetWParam(cae->cae, param, value);
#endif
}

int Netease_CAEGetWParam(CAEDATA *cae, const char *param, char *value,
                         unsigned int *valueLen) {
#ifndef Link_Hidden
    return api_cae_get_wparam(cae->cae, param, value, valueLen);
#else
    return CAEGetWParam(cae->cae, param, value, valueLen);
#endif
}

char *Netease_CAEGetVersion() {
#ifndef Link_Hidden
    return api_cae_get_version();
#else
    return CAEGetVersion();
#endif
}

int Netease_CAEGetChannel() {
#ifndef Link_Hidden
    return api_cae_get_channel();
#else
    return CAEGetChannel();
#endif
}

int Netease_CAESetShowLog(int show_log) {
#ifndef Link_Hidden
    return api_cae_set_show_log(show_log);
#else
    CAESetShowLog(show_log);
#endif
}
