// db_adapter.hpp
#ifndef DEK_ADAPTER_HPP
#define DEK_ADAPTER_HPP

#include <string>
#include <queue>
#include <unordered_map>
#include <memory>
#include "kms/kms_common.hpp"

class DekManager {
private:
    std::string user_name_;
    std::string db_name_;
    std::string table_name_;
    std::queue<std::string> col_name_;
    std::unordered_map<std::string, std::string> col_dek_;
    std::unordered_map<std::string, std::string> col_dek_update_;
    std::string table_dek_;
    std::string table_dek_update_;

    DekManager() = default;
    DekManager(const std::string& user_name, const std::string& db_name ):user_name_(user_name),db_name_(db_name){}
    
public:
    ~DekManager() = default;
    DekManager(const DekManager&) = delete;
    DekManager& operator=(const DekManager&) = delete;


    static DekManager& getInstance() {
        static thread_local DekManager instance;
        return instance;
    }

    void initialize(const std::string& user_name, const std::string& db_name);


    // DEK 管理
    // bool storeDek(const DEK& dek);
    // bool deleteDek(const std::string& user_name, const std::string& table, const std::string& column);
    // bool createDek(std::string& col_dek, const std::string& column_name);

    // 数据库信息设置
    void setInfoUser(const std::string& user_name);
    void setInfoDb(const std::string& db_name);
    void setInfoTable(const std::string& table_name);
    void setInfoCol(const std::string& col_name);
    std::string getInfoUser();
    std::string getInfoDb();
    std::string getInfoTable();
    std::string getInfoCol();

    // DEK 缓存管理
    // Col Level
    void setDekColLevel(const std::string& col_name, const std::string& dek_tmp);
    void getDekColLevel(const std::string& col_name, std::string& dek_tmp);
    void setDekColLevelForUpdate(const std::string& col_name, const std::string& dek_tmp) ;
    void getDekColLevelForUpdate(const std::string& col_name, std::string& dek_tmp) ;

    // Tabel Level
    void setDekTableLevel(const std::string& dek);
    void getDekTableLevel(std::string& dek);
    void setDekTableLevelForUpdate(const std::string& dek);
    void getDekTableLevelForUpdate(std::string& dek) ;
    

    void getAllDekColLevelForUpdate(std::unordered_map<std::string, std::string>& column_deks) ;

    void clearDek() ;
    void clearDekForUpdate() ;

    // ORE 专用 DEK
    // void setDekOnlyForOre(const std::string& dek) ;
    // void clearDekOnlyForOre() ;
    // char* getDekOnlyForOre() ;

    bool isRotateCmd(){
        return table_dek_update_ != "" || col_dek_update_.size() != 0;
    }
};

#endif // DB_ADAPTER_HPP