/*
 * Copyright 2024 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 "error.h"

#include <kylin-ai/ai-engine/aiengineerror.h>

#include <map>

#include "assistant/intentdialoguemanager/dialoguemessage.h"
#include "business/knowledge-base/common.h"

namespace assistant {

std::map<ai_engine::NlpEngineErrorCode, assistant::ErrorCode> nlpEngineErrorMap{
    {ai_engine::NlpEngineErrorCode(-1), ErrorCode::Ok},
    {ai_engine::NlpEngineErrorCode::NomoreMemory, ErrorCode::NlpServerError},
    {ai_engine::NlpEngineErrorCode::NetworkDisconnected, ErrorCode::NetError},
    {ai_engine::NlpEngineErrorCode::NetworkLatencyTooLong, ErrorCode::NetError},
    {ai_engine::NlpEngineErrorCode::FailedToConnectServer, ErrorCode::NetError},
    {ai_engine::NlpEngineErrorCode::ServerNoResponse, ErrorCode::NlpServerError},
    {ai_engine::NlpEngineErrorCode::NoServerService, ErrorCode::NlpServerError},
    {ai_engine::NlpEngineErrorCode::Unauthorized, ErrorCode::UnAuthorized},
    {ai_engine::NlpEngineErrorCode::TooLittleParams, ErrorCode::ParamError},
    {ai_engine::NlpEngineErrorCode::TooManyParams, ErrorCode::ParamError},
    {ai_engine::NlpEngineErrorCode::InvalidWords, ErrorCode::NetError},
    {ai_engine::NlpEngineErrorCode::InvalidParamType, ErrorCode::ParamError},
    {ai_engine::NlpEngineErrorCode::TooLittleData, ErrorCode::ParamError},
    {ai_engine::NlpEngineErrorCode::TooManyData, ErrorCode::ParamError},
    {ai_engine::NlpEngineErrorCode::TooFrequentRequest, ErrorCode::RequestTooMany},
    {ai_engine::NlpEngineErrorCode::TooManyRequest, ErrorCode::RequestTooMany},
    {ai_engine::NlpEngineErrorCode::FailedToAnswer, ErrorCode::NlpServerError},
    {ai_engine::NlpEngineErrorCode::InputTextBlocked, ErrorCode::InputTextBlocked},
    {ai_engine::NlpEngineErrorCode::OutputTextBlocked, ErrorCode::OutputTextBlocked},
    {ai_engine::NlpEngineErrorCode::FreeAllocatedQuotaExceeded, ErrorCode::FreeAllocatedQuotaExceeded},
    {ai_engine::NlpEngineErrorCode::LocalNlpModelNotLoaded, ErrorCode::LocalNlpModelNotLoaded},
    {ai_engine::NlpEngineErrorCode::SslCertificateError, ErrorCode::SslCertificateError},
};

std::map<ai_engine::VisionEngineErrorCode, assistant::ErrorCode> visionEngineErrorMap{
    {ai_engine::VisionEngineErrorCode(-1), ErrorCode::Ok},
    {ai_engine::VisionEngineErrorCode::NomoreMemory, ErrorCode::NlpServerError},
    {ai_engine::VisionEngineErrorCode::NetworkDisconnected, ErrorCode::NetError},
    {ai_engine::VisionEngineErrorCode::NetworkLatencyTooLong, ErrorCode::NetError},
    {ai_engine::VisionEngineErrorCode::FailedToConnectServer, ErrorCode::NetError},
    {ai_engine::VisionEngineErrorCode::ServerNoResponse, ErrorCode::NlpServerError},
    {ai_engine::VisionEngineErrorCode::NoServerService, ErrorCode::NlpServerError},
    {ai_engine::VisionEngineErrorCode::Unauthorized, ErrorCode::UnAuthorized},
    {ai_engine::VisionEngineErrorCode::TooLittleParams, ErrorCode::ParamError},
    {ai_engine::VisionEngineErrorCode::TooManyParams, ErrorCode::ParamError},
    {ai_engine::VisionEngineErrorCode::InvalidParamType, ErrorCode::ParamError},
    {ai_engine::VisionEngineErrorCode::TooLittleData, ErrorCode::ParamError},
    {ai_engine::VisionEngineErrorCode::TooManyData, ErrorCode::ParamError},
    {ai_engine::VisionEngineErrorCode::TooFrequentRequest, ErrorCode::RequestTooMany},
    {ai_engine::VisionEngineErrorCode::TooManyRequest, ErrorCode::RequestTooMany},
    {ai_engine::VisionEngineErrorCode::Invalidwords, ErrorCode::InputTextInvaild},
    {ai_engine::VisionEngineErrorCode::ImageGenerationFailed, ErrorCode::GenerateImageFailed},
    {ai_engine::VisionEngineErrorCode::ImageCensorshipFailed, ErrorCode::GenerateImageBlocked},
    {ai_engine::VisionEngineErrorCode::SslCertificateError, ErrorCode::SslCertificateError},
};

std::map<DialogueCallback::DialogueControlErrorCode, assistant::ErrorCode> DialogueControlErrorMap{
    {DialogueCallback::DialogueControlErrorCode::InvalidInput, ErrorCode::InputTextInvaild},
    {DialogueCallback::DialogueControlErrorCode::SystemOperationFailed, ErrorCode::SystemOperationFailed},
    {DialogueCallback::DialogueControlErrorCode::IntentionRecognitionFailed, ErrorCode::IntentionRecognitionFailed},
};

std::map<knowledgebase::KnowledgebaseErrorCode, assistant::ErrorCode> FileKnowledgeBaseErrorMap{
    {knowledgebase::KnowledgebaseErrorCode::KNOWLEDGEBASE_CHUNK_FAILED, ErrorCode::FileParseFailed},
    {knowledgebase::KnowledgebaseErrorCode::KNOWLEDGEBASE_DOCUMENT_EXCEEDS_LIMIT, ErrorCode::FileExceedSizeLimit},
    {knowledgebase::KnowledgebaseErrorCode::KNOWLEDGEBASE_VECTOR_DATABASE_DATA_UNAVAILABLE,
     ErrorCode::FileDatabaseCorrupted},
};

ErrorCode Error::getErrorCodeFromNlpEngine(int engineErrorCode) {
    auto code = ai_engine::NlpEngineErrorCode(engineErrorCode);
    if (nlpEngineErrorMap.find(code) != nlpEngineErrorMap.end()) {
        return nlpEngineErrorMap[code];
    }
    return ErrorCode::UnknownError;
}

ErrorCode Error::getErrorCodeFromVisionEngine(int engineErrorCode) {
    auto code = ai_engine::VisionEngineErrorCode(engineErrorCode);
    if (visionEngineErrorMap.find(code) != visionEngineErrorMap.end()) {
        return visionEngineErrorMap[code];
    }
    return ErrorCode::UnknownError;
}

ErrorCode Error::getErrorCodeFromDialogueControl(int dialogueErrorCode) {
    if (dialogueErrorCode == 0 || dialogueErrorCode == -1) {
        return ErrorCode::Ok;
    }

    if (DialogueControlErrorMap.find((DialogueCallback::DialogueControlErrorCode)dialogueErrorCode) !=
        DialogueControlErrorMap.end()) {
        return static_cast<ErrorCode>(
            DialogueControlErrorMap[(DialogueCallback::DialogueControlErrorCode)dialogueErrorCode]);
    }

    return ErrorCode::UnknownError;
}

ErrorCode Error::getErrorCodeFromFileKnowledgeBase(int engineErrorCode) {
    if (engineErrorCode == 0) {
        return ErrorCode::Ok;
    }

    if (FileKnowledgeBaseErrorMap.find((knowledgebase::KnowledgebaseErrorCode)engineErrorCode) !=
        FileKnowledgeBaseErrorMap.end()) {
        return static_cast<ErrorCode>(
            FileKnowledgeBaseErrorMap[(knowledgebase::KnowledgebaseErrorCode)engineErrorCode]);
    }

    return ErrorCode::UnknownError;
}

}  // namespace assistant
