/*
 * Copyright (C) 2020, KylinSoft Co., Ltd.
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */
#include "recorder.h"

#include <QIODevice>
#include <QThread>
#include <ukui-log4qt.h>

/**
 * @brief chatCallback
 *          聊天结果返回回调函数，数据流式返回
 * @param result
 * @param usr_data
 */
static void speechCallback(SpeechRecognitionResult *result, void *usr_data)
{
    if(usr_data == nullptr)
    {
        KyInfo() << "Invalid callback user data pointer.";
    }
    int errorCode = speech_recognition_result_get_error_code(result);
    const char *result_text = speech_recognition_result_get_text(result);
    SpeechResultReason reason = speech_recognition_result_get_reason(result);
    const char *errMsg = speech_recognition_result_get_error_message(result);
    KyInfo() << "ddddddddddd reason :" << reason;
    KyInfo() << "ddddddddddd errorCode :" << errorCode;
    KyInfo() << "ddddddddddd result_text :" << result_text;
    KyInfo() << "ddddddddddd errMsg :" << errMsg;


    Recorder *recorder = (Recorder *)usr_data;
    if(errorCode != 0 &&  errorCode != -1)
    {
        QString errorStr = Globals::getErrorMsg(static_cast<SpeechErrorCode>(errorCode));
        Q_EMIT recorder->reply(errorStr, true, 0, errorCode);
        Q_EMIT recorder->sigCancelSendVoice();
    }
    else
    {
        if (reason == SPEECH_RECOGNIZING)
        {
            Q_EMIT recorder->sigSendTmpMsg(QString::fromStdString(result_text));

        }
        else if (reason == SPEECH_RECOGNIZED)
        {
            Q_EMIT recorder->sigSendMsg(QString::fromStdString(result_text));
        }
    }
}
Recorder::Recorder(QObject *parent)
    : QObject(parent)
{

}

Recorder::~Recorder()
{
    if(config != nullptr){
        AudioConfig **cConfig = &config;
        audio_config_destroy(cConfig);
    }
    closeSession();

}

//单次语音处理
void Recorder::startRecord()
{
    if(!initSession())
    {
        Q_EMIT sigCancelSendVoice();
        return;
    }

    qDebug() << "startRecordInput";

    //现在直接使用默认麦克风作为数据
    config =audio_config_create_continuous_audio_input_from_default_microphone();
    speech_recognizer_set_audio_config(session, config);
    speech_recognizer_start_continuous_recognition_async(session);

    Q_EMIT sigIsStartTimer();
}

void Recorder::stopRecord()
{

    if(this->session){
        speech_recognizer_stop_continuous_recognition_async(session);
    }
}

bool Recorder::initSession()
{
    QString error;
    //初始化会话时，对创建成功的会话进行判断并进行指针传递，如果创建失败则返回错误码
    if(this->session != nullptr)
        return true;
    SpeechRecognitionSession *session = nullptr;
    KyInfo() << "*** start initSession speech_recognizer_create_session()";
    session = speech_recognizer_create_session();
    if(session != nullptr)
    {
        KyInfo() << "speech_recognizer_create_session successful.";
    }
    else
    {
        KyInfo() << "speech_recognizer_create_session error.";
        Q_EMIT sigCancelSendVoice();
        return false;
    }
    KyInfo() << "*** end initSession speech_recognizer_create_session()";

    KyInfo() << "*** start initSession speech_recognizer_init_session()";

    int ret = speech_recognizer_init_session(session);
    if(!ret)
    {
        KyInfo() << "speech_init_session successful";
    }
    else
    {
        KyInfo() << "speech_init_session error:" << ret;
        error = Globals::getErrorMsg(static_cast<SpeechErrorCode>(ret));
        Q_EMIT reply(error, true, 0, ret);
        Q_EMIT sigCancelSendVoice();
        return false;
    }

    KyInfo() << "*** end initSession speech_recognizer_init_session()";

    if(!ret)
    {
        this->session = session;
        //单次语音识别使用recognized接收结果
        speech_recognizer_result_set_callback(session, speechCallback, this);
    }
    return true;
}

void Recorder::closeSession()
{
    if(this->session != nullptr){
        SpeechRecognitionSession **sSession = &session;
        speech_recognizer_destroy_session(sSession);
    }
    this->session = nullptr;
}
