// local_kms_core.hpp
#ifndef LOCAL_KMS_CORE_HPP
#define LOCAL_KMS_CORE_HPP

#pragma once

#include <string>
#include <vector>
#include <queue>
#include <iostream>
#include <ctime>
#include <fstream>
#include <random>
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <openssl/sha.h>
#include <sstream>
#include <iomanip>
#include <algorithm>
//#include <libpq-fe.h>
#include "json.hpp"

#include <thread>
#include <chrono>
#include <mutex>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <map>

#include "kms_factory.hpp"
#include "kms_interface.hpp"
#include "kms_common.hpp"
#include "json.hpp"

using json = nlohmann::json;

class LocalKmsCore : public IKmsCore {
private:
    json _data;                                 // 解析出的 JSON 数据
    std::string _path;                          // CMK 信息存储路径（JSON 文件）
    std::string _key_path;                      // 加密 CMK 的密钥路径
    std::string _user_name;
    std::string _db_name;
    std::string _cmk;                           // 当前用户的 CMK
    std::string _cmk_auto_rotate_status_path;   // CMK 自动轮转状态存储路径
    std::map<std::string, pid_t> cmk_auto_rotate_pids; // 自动轮转进程 ID
    std::map<std::string, bool> cmk_auto_rotate_status; // 自动轮转状态

    std::vector<unsigned char> readBinaryFile(const std::string& path);
    std::vector<unsigned char> xorBuffers(const std::vector<unsigned char>& a, const std::vector<unsigned char>& b);
    std::vector<unsigned char> hmac_sha256(const std::vector<unsigned char>& key, const std::vector<unsigned char>& message);
    std::vector<unsigned char> getSystemIDHash16();
    std::vector<unsigned char> sha256(const std::string& input);
    std::string base64_encode(const unsigned char *data, size_t length);
    std::string base64_decode(const std::string &encoded);

    void getRootKey(unsigned char *key, size_t len);
    std::string deriveKey(const std::string& master_key, const std::string& column_name);
    std::string generateSalt(const std::string& column_name);
    bool getRandomCmk(std::string &_cmk_data, AlgorithmType alg, int &length);
    bool getRandomDek(std::string &_dek_data);
    void _rand(std::string &rand, int length_in_bytes);
    bool encryptKey(std::string &ori_key);
    bool decryptKey(std::string &ori_key);
    bool createDerivedDek(std::string& dek, const std::string& column_name);

    void loadAutoRotateStatus();
    void saveAutoRotateStatus();
    void autoRotateProcess(const std::string &user_name);
    bool storeCmk(CMK &cmk, bool rotate=false);
    bool LoadCmkByUsername(const std::string &user_name);
    bool save();
public:
    LocalKmsCore(const IKmsConfig &config);
    ~LocalKmsCore();

    // KMSInterface 实现
    bool init() override;

    // cmk 相关
    bool hasCmk(const std::string &user_name) const override;
    bool createCmk(const std::string& user_name, int rotate_period,
                   KeyStruct ks = KeyStruct::RAW, AlgorithmType alg = AlgorithmType::AES128) override;
    bool deleteCmk(const std::string& user_name) override;
    bool describeCmk(const std::string &user_name, std::string &result, bool decrypt) override;

    // 自动轮转辅助方法
    bool rotateCmkNow(const std::string& user_name) override;
    bool handleAutoRotateCmd(std::string* auto_rotate_action, const std::string& user_name) override;
    bool getCmkAutoRotateStatusByUsername(const std::string& user_name) override;
    
    // 加解密
    bool encryptData(std::string& dek) override;
    bool decryptData(std::string& dek) override;
    
    // 新建DEK
    bool createDek(std::string &col_dek, const std::string &column_name) override;

    static void registerLocalKms(){
        KmsFactory::instance().registerCreator("local", [](const IKmsConfig& config) {
            return myPtr::make_unique<LocalKmsCore>(config);
        });
    }
};

#endif // LOCAL_KMS_CORE_HPP