// db_interface.hpp
#ifndef DB_INTERFACE_HPP
#define DB_INTERFACE_HPP

#ifdef __cplusplus
extern "C"
{
#endif

#include "postgres.h" // 与 #include <iomanip> 冲突
//为了解决和libintl.h冲突的问题undef以下4个
#undef gettext
#undef dgettext
#undef ngettext
#undef dngettext

#include "utils/palloc.h"
#include "utils/memutils.h"

#include "nodes/nodes.h"
#include "nodes/parsenodes.h"
#include "nodes/value.h"

#include "base64.h"

#include <string.h>
#ifdef __cplusplus
}
#endif

#include "encryptsql/fieldmap.h"
#include <assert.h>
#include <stdexcept>
#include <set>
#include <vector>
#include <string>
#include "libpq-fe.h"  // 改为使用引号包含

#include "crypto/crypto.h"
#include "crypto/openssl.h"
#include "encryptsql.h"


// 因为缺头文件所以直接复制过来了，肯定有很多用不上的
#include <regex>
#include <iostream>
#include <unordered_set>
#include <string>
#include <unordered_map>

#include "json.hpp"
#include "kms/kms_common.hpp"
#include "dek_manager.hpp"

// 数据库连接信息
#define DB_CONNINFO "dbname=dekmaster user=dekmaster password=secure_password hostaddr=127.0.0.1 port=5432"
#define BACKUP_TABLE_NAME "dek_store_backup"
#define ORIGINAL_TABLE_NAME "dek_store"


namespace DekInterface {

    // 获取当前线程的 DBAdapter 实例
    inline DekManager& getAdapter() {
        return DekManager::getInstance();
    }

    // 初始化接口
    inline void initialize(const std::string& user_name, const std::string& db_name) {
        getAdapter().initialize(user_name, db_name);
    }

    // DEK 管理接口
    // inline bool storeDek(const DEK& dek) {
    //     return getAdapter().storeDek(dek);
    // }

    // inline bool deleteDek(const std::string& user_name, const std::string& table, const std::string& column) {
    //     return getAdapter().deleteDek(user_name, table, column);
    // }

    // inline bool createDek(std::string& col_dek, const std::string& column_name) {
    //     return getAdapter().createDek(col_dek, column_name);
    // }

    // 数据库信息设置接口
    inline void setInfoUser(const std::string& user_name) {
        getAdapter().setInfoUser(user_name);
    }

    inline void setInfoDb(const std::string& db_name) {
        getAdapter().setInfoDb(db_name);
    }

    inline void setInfoTable(const std::string& table_name) {
        getAdapter().setInfoTable(table_name);
    }

    inline void setInfoCol(const std::string& col_name) {
        getAdapter().setInfoCol(col_name);
    }

    // 数据库信息获取接口
    inline std::string getInfoUser() {
        return getAdapter().getInfoUser();
    }

    inline std::string getInfoDb() {
        return getAdapter().getInfoDb();
    }

    inline std::string getInfoTable() {
        return getAdapter().getInfoTable();
    }

    inline std::string getInfoCol() {
        return getAdapter().getInfoCol();
    }

    // DEK 缓存管理接口
    inline void setDekColLevel(const std::string& col_name, const std::string& dek_tmp) {
        getAdapter().setDekColLevel(col_name, dek_tmp);
    }

    inline void getDekColLevel(const std::string& col_name, std::string& dek_tmp) {
        getAdapter().getDekColLevel(col_name, dek_tmp);
    }

    inline void setDekTableLevel(const std::string& dek) {
        getAdapter().setDekTableLevel(dek);
    }

    inline void getDekTableLevel(std::string& dek) {
        getAdapter().getDekTableLevel(dek);
    }

    inline void setDekTableLevelForUpdate(const std::string& dek) {
        getAdapter().setDekTableLevelForUpdate(dek);
    }

    inline void getDekTableLevelForUpdate(std::string& dek) {
        getAdapter().getDekTableLevelForUpdate(dek);
    }

    inline void setDekColLevelForUpdate(const std::string& col_name, const std::string& dek_tmp) {
        getAdapter().setDekColLevelForUpdate(col_name, dek_tmp);
    }

    inline void getDekColLevelForUpdate(const std::string& col_name, std::string& dek_tmp) {
        getAdapter().getDekColLevelForUpdate(col_name, dek_tmp);
    }

    inline void getAllDekColLevelForUpdate(std::unordered_map<std::string, std::string>& column_deks) {
        getAdapter().getAllDekColLevelForUpdate(column_deks);
    }

    inline void clearDek() {
        getAdapter().clearDek();
    }

    inline void clearDekForUpdate() {
        getAdapter().clearDekForUpdate();
    }

    // ORE 专用 DEK 接口
    // inline void setDekOnlyForOre(const std::string& dek) {
    //     getAdapter().setDekOnlyForOre(dek);
    // }

    // inline void clearDekOnlyForOre() {
    //     getAdapter().clearDekOnlyForOre();
    // }

    // inline char* getDekOnlyForOre() {
    //     return getAdapter().getDekOnlyForOre();
    // }

    inline bool isRotateCmd(){
        return getAdapter().isRotateCmd();
    }

    // 定义轮换类型枚举
    enum RotationType {
        ROTATE_ALL,      // 轮换表级和所有列级密钥
        ROTATE_TABLE,    // 只轮换表级密钥
        ROTATE_COLUMNS   // 只轮换指定列的密钥
    };

    // 轮换命令解析结果结构
    struct RotateCommandResult {
        bool valid;                  // 命令是否有效
        RotationType type;           // 轮换类型
        std::string tableName;       // 表名
        std::string enc_tableName;   // 加密表名

        std::set<std::string> cols_set; // 命令涉及的列名列表 用于快速检索轮换命令中是否有这个列
        std::unordered_set<std::string> enc_cols_set; // 需要更新的密钥的密文列名

        std::unordered_map<std::string, std::string> col_map; // 明文列名 和 密文列名的映射
        std::unordered_map<std::string, std::string> col_type; // 列的类型
        std::string errorMessage;    // 错误信息
    };

    RotateCommandResult parseRotateCommand(const std::string& command,const std::string &user_name,const std::string &db_name);

    // test
    void printRotateCommandResult(const RotateCommandResult& result);

    void connectionDelete();

    void connectionUpdateDek(RotateCommandResult &result);

    void connectionUpdateDek_Init(RotateCommandResult &result);

    void connectionUpdateDek_Update(RotateCommandResult& result);

    void connectionUpdateDek_Final(RotateCommandResult& result);

    void connectionInsertTest();

    void connectionSelectTest();

    void connectionSelect();

    using json = nlohmann::json;

    // 读取 JSON 文件
    json read_json_from_file(const std::string& file_path);

    // 获取表中所有列
    std::vector<std::string> get_columns(const std::string& table_name, const json& j);

    // 获取表中所有列
    std::set<std::string> get_all_columns(const std::string& table_name, const json& j);

    // 获取表中列的映射关系
    std::unordered_map<std::string, std::string> get_column_mapping(const std::string& table_name, const json& j);

    // 获取列的数据类型
    std::string get_column_type(const std::string& table_name, const std::string& column_name, const json& j);


    static int executeSQL(const char *sql, const char *errorMsg);

    static int tableExists(const char *tableName);

    int backupDekStore();

    int deleteDekStoreBackup();

    int restoreDekStore();

} // namespace DekAPI

#endif // DB_INTERFACE_HPP