/*
 * 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 "_genaitextsession.h"

#include <map>

#include "_chatmessage.h"
#include "_chatmodelconfig.h"
#include "chat.h"
#include "error.h"
#include "logger.h"

GenAiTextSession *genai_text_create_session() {
    return new _GenAiTextSession{};
}

void genai_text_destroy_session(GenAiTextSession **session) {
    if (session == nullptr) {
        return;
    }
    if (*session == nullptr) {
        return;
    }
    (*session)->destroy();
    delete *session;
    *session = nullptr;
}

int genai_text_init_session(GenAiTextSession *session) {
    if (session == nullptr) {
        return AISDK_INVALID_SESSION;
    }
    return session->init();
}

void genai_text_result_set_callback(GenAiTextSession *session,
                                    ChatResultCallback callback,
                                    void *user_data) {
    if (session == nullptr) {
        return;
    }
    session->setResultCallback(callback, user_data);
}

void genai_text_set_model_config(GenAiTextSession *session,
                                 ChatModelConfig *config) {
    if (session == nullptr) {
        return;
    }

    if (config == nullptr) {
        session->setChatModelConfig(ChatModelConfig{
            std::string{}, ModelDeployType{ModelDeployType(-1)}, int{}});
        return;
    }

    session->setChatModelConfig(*config);
}

// 根据提示进行文本生成补全
void genai_text_generate_content_async(GenAiTextSession *session,
                                       const char *prompt) {
    if (session == nullptr) {
        return;
    }
    genai_text_set_chat_system_prompt_id(session, TEXT_EXPANSION);
    genai_text_chat_async(session, prompt);
}

// 进行对话，支持缓存上下文
void genai_text_chat_async(GenAiTextSession *session, const char *question) {
    if (session == nullptr) {
        return;
    }
    session->chat(question);
}

// 进行对话，需要传入历史消息
void genai_text_chat_with_history_messages_async(
    GenAiTextSession *session, ChatMessage *history_messages) {
    if (session == nullptr) {
        return;
    }
    session->chatWithHistoryMessages(*history_messages);
}

// 设置对话提示词
void genai_text_set_chat_system_prompt(GenAiTextSession *session,
                                       const char *prompt) {
    if (session == nullptr or prompt == nullptr) {
        return;
    }
    session->setChatSystemPrompt(prompt);
}

// 设置对话的提示词，使用SDK内置的提示词
void genai_text_set_chat_system_prompt_id(GenAiTextSession *session,
                                          PromptId prompt_id) {
    if (session == nullptr) {
        return;
    }
    session->setChatSystemPromptId(prompt_id);
}

// 清除对话上下文
void genai_text_clear_chat_history_messages(GenAiTextSession *session) {
    if (session == nullptr) {
        return;
    }
    session->clearChatMessage();
}

void genai_text_stop_chat(GenAiTextSession *session) {
    if (session == nullptr) {
        return;
    }
    session->stopChat();
}

// 类：_GenaiTextSession成员函数定义

_GenAiTextSession::_GenAiTextSession() {
    serviceProxy_.setReconnectedCallback([this]() { initSession(); });
}

int _GenAiTextSession::init() {
    if (!initServer()) {
        return AiSdkCommonErrorCode::AISDK_RUNTIME_ERROR;
    }

    return initSession();
}

void _GenAiTextSession::destroy() { serviceProxy_.destroyEngine(sessionId_); }

void _GenAiTextSession::setResultCallback(const ChatResultCallback &callback,
                                          void *userData) {
    serviceProxy_.setChatResultCallback(callback, userData);
}

void _GenAiTextSession::setChatModelConfig(
    const ChatModelConfig &chatModelConfig) {
    chatModelConfig_ = chatModelConfig;
}

void _GenAiTextSession::chat(const std::string &question) {
    serviceProxy_.chat(sessionId_, chatModelConfig_, question);
}

void _GenAiTextSession::chatWithHistoryMessages(const ChatMessage &message) {
    serviceProxy_.chatWithHistoryMessages(sessionId_, chatModelConfig_,
                                          message.generateJsonString());
}

void _GenAiTextSession::setChatSystemPrompt(const std::string &message) {
    serviceProxy_.addSystemMessage(sessionId_, message);
}

void _GenAiTextSession::setChatSystemPromptId(PromptId promptId) {
    serviceProxy_.setChatSystemPromptId(sessionId_, promptId);
}

void _GenAiTextSession::stopChat() { serviceProxy_.stopChat(sessionId_); }

void _GenAiTextSession::clearChatMessage() {
    serviceProxy_.clearChatMessage(sessionId_);
}

bool _GenAiTextSession::initServer() {
    if (!serviceProxy_.connectToServer()) {
        return serviceProxy_.reconnectServer();
    }
    return true;
}

int _GenAiTextSession::initSession() {
    int errorCode = serviceProxy_.initEngine(chatModelConfig_, &sessionId_);
    if (errorCode != AISDK_NO_ERROR) {
        LOGE("Init session error: ", errorCode);
    }
    return errorCode;
}