#include <fstream>
#include <assert.h>
#include <cstring>
#include <atomic>
#include <unistd.h>
#include <string>

#include "JZsdkLib.h"
#include "version_choose.h"

#ifdef IFLAY_TTS_2_CONFIG_STATUS_ON

#include "aikit_biz_api.h"
#include "aikit_constant.h"
#include "aikit_biz_config.h"
#include "iflytek_tts.h"
#include "AudioDeal/AudioDeal.h"
#include "../../Megaphone.h"
#include "iflytek_tts.h"


using namespace std;
using namespace AIKIT;

static std::atomic_bool ttsFinished(false);
static const char *ABILITY = "e2e44feff";
static AIKIT_HANDLE *g_AikitHandle = nullptr; //合成句柄

static int IflytekLib_2_StopTts();

static FILE *iflytts_fp = NULL;
#define IFLYTTS_FP_NAME "/root/tmp_tts_file.pcm"


void OnOutput(AIKIT_HANDLE* handle, const AIKIT_OutputData* output) 
{
    //检测数据生成标志位是否有关闭,如果有关闭,则主动关闭合成,并退出该事件
    if (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) == JZ_FLAGCODE_OFF)
    {
        IflytekLib_2_StopTts();
        return;
    }
    
    //如果存在数据,则播放
    if (output->node->value) 
    {
        //生产的文本数据 output->node->value
        //生产的数据长度 output->node->len
        //char类型

        //JZSDK_LOG_DEBUG("生产了数据%d", output->node->len);
        printf("生产了数据%d\n", output->node->len);

        //将该数据发送到alsa播放器
        //AudioDeal_PcmDataInput_TextSteam(16000, (unsigned char *)output->node->value, output->node->len);

        if (iflytts_fp != NULL)
        {
            fwrite(output->node->value, sizeof(char), output->node->len, iflytts_fp);
            fflush(iflytts_fp);
        }
        
    }


}

void OnEvent(AIKIT_HANDLE* handle, AIKIT_EVENT eventType, const AIKIT_OutputEvent* eventValue) {
    if (eventType == AIKIT_Event_End) {
        ttsFinished = true;

        JZSDK_LOG_INFO("合成完成");
    }
}

void OnError(AIKIT_HANDLE* handle, int32_t err, const char* desc) {
    printf("OnError:%d\n", err);

    //报错
}

int IflytekLib_2_TextToTts(int language, 
                            const char *TtsRole, 
                            const char *text, int speed, int volume)
{
    
    if (iflytts_fp != NULL)
    {
        JZSDK_LOG_ERROR("file %s is not closed\n", IFLYTTS_FP_NAME);
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }
    

    AIKIT_ParamBuilder* paramBuilder = nullptr;
    AIKIT_DataBuilder* dataBuilder = nullptr;   
    AiText* aiText_raw = nullptr;


    // 重置完成标志
    ttsFinished = false;
    
    paramBuilder = AIKIT_ParamBuilder::create();
    paramBuilder->clear();
    // 设置发音人
    paramBuilder->param("vcn", TtsRole, strlen(TtsRole));
    paramBuilder->param("vcnModel", TtsRole, strlen(TtsRole));
    // 设置语种
    paramBuilder->param("language", language);
    // 设置文本编码
    paramBuilder->param("textEncoding", "UTF-8", strlen("UTF-8"));

    //语速
    paramBuilder->param("speed",speed); //可选参数,默认为0
    
    //音调
    //paramBuilder->param("pitch",100); //可选参数,默认为0
    
    //声音
    //paramBuilder->param("volume",100);//可选参数,默认为0

    //打开临存文件
    iflytts_fp = fopen(IFLYTTS_FP_NAME, "w+b");
    if (iflytts_fp == NULL)
    {
        JZSDK_LOG_ERROR("open file %s failed\n", IFLYTTS_FP_NAME);
        return JZ_ERROR_SYSTEM_MODULE_CODE_FAILURE;
    }

    //JZSDK_LOG_DEBUG("TTS Role:%s Len:%d, Text:%s Len:%d, language:%d", TtsRole, strlen(TtsRole), text, strlen(text), language);
    
    int ret = AIKIT_Start(ABILITY, AIKIT_Builder::build(paramBuilder), nullptr, &g_AikitHandle);
    if(ret != 0) {
        printf("AIKIT_Start failed: %d\n", ret);
        goto exit;
    }

    dataBuilder = AIKIT_DataBuilder::create();
    dataBuilder->clear();
    //aiText_raw = AiText::get("text")->data(text.c_str(), text.length())->once()->valid();
    aiText_raw = AiText::get("text")->data(text, strlen(text) )->once()->valid();
    dataBuilder->payload(aiText_raw);

    ret = AIKIT_Write(g_AikitHandle, AIKIT_Builder::build(dataBuilder));
    if(ret != 0) {
        printf("AIKIT_Write failed: %d\n", ret);
        goto exit;
    }

    // 等待合成完成
    while(!ttsFinished) {
        usleep(1000);
    }

    JZSDK_LOG_DEBUG("合成完成,开始播放");

    //将fp指针移到文件开头
    fseek(iflytts_fp, 0, SEEK_SET);

    //将数据导入播放器
    unsigned char buffer[1024];
    int len;
    while (Megaphone_MegDataGenFlag(JZ_FLAGCODE_GET, 0) != JZ_FLAGCODE_OFF)
    {
        len = fread(buffer, sizeof(char), 1024, iflytts_fp);
        if (len <= 0)
        {
            JZSDK_LOG_DEBUG("已读取完毕\n");
            break;
        }

        AudioDeal_PcmDataInput_TextSteam(16000, buffer, len);
    }

    JZSDK_LOG_INFO("播放完成");
    
    ret = AIKIT_End(g_AikitHandle);

exit:      
    if(paramBuilder != nullptr) {
        delete paramBuilder;
    }
    if(dataBuilder != nullptr) {
        delete dataBuilder;
    }

    if (iflytts_fp != NULL)
    {
        fclose(iflytts_fp);
        iflytts_fp = NULL;
    }

    return 0;
}











int IflytekLib_2_Init()
{
    AIKIT_Configurator::builder()
        .app()
            .appID("03857dfd")
            .apiSecret("OTA2OTEzMTVlOGYwMjllMmJkYzEwZGY5")
            .apiKey("2b2c60f8a80b8cdfe45ae1058a25149a")
            .workDir("/root/Iflytek_2")
        .auth()
            .authType(0)
        .log()
            .logLevel(LOG_LVL_OFF)      //关闭日志打印
            .logMode(LOG_STDOUT);        //日志输出为控制台        
            
    int ret = AIKIT_Init();
    if(ret != 0) {
        printf("AIKIT_Init failed: %d\n", ret);
        return -1;
    }
    
    AIKIT_Callbacks cbs = {OnOutput, OnEvent, OnError};
    AIKIT_RegisterAbilityCallback(ABILITY, cbs);

    return 0;
}

int IflytekLib_2_UnInit()
{
    AIKIT_UnInit();
    return 0;
}

static int IflytekLib_2_StopTts()
{
    AIKIT_OutputEvent eventData = {};
    if (g_AikitHandle != nullptr)
    {
        OnEvent(g_AikitHandle,AIKIT_Event_End,&eventData);
    }
    
    return 0;
}

#endif