// kms_interface.cpp
#include "kms/kms_interface.hpp"
#include "kms/kms_factory.hpp"
#include <utility>  


// 线程局部存储：每个线程维护一份 IKmsCore 实例
thread_local std::unique_ptr<IKmsCore> KMSInterface::instance_ = nullptr;

bool KMSInterface::initialize(const IKmsConfig& config) {
    if (instance_) {
        return true;
    }

    try {
        instance_ = KmsFactory::instance().create(config);
        if (instance_) {
            instance_->init();
            return true;
        }
    } catch (const std::exception& e) {
        // 记录日志
        return false;
    }
    return false;
}

void KMSInterface::cleanup() {
    instance_.reset();
}

IKmsCore* KMSInterface::getInstance() {
    return instance_.get();
}

bool KMSInterface::hasCmk(const std::string& user_name) {
    return instance_ && instance_->hasCmk(user_name);
}

bool KMSInterface::createCmk(const std::string& user_name, int rotate_period,
                             KeyStruct ks, AlgorithmType alg) {
    return instance_ && instance_->createCmk(user_name, rotate_period, ks, alg);
}

bool KMSInterface::deleteCmk(const std::string& user_name) {
    return instance_ && instance_->deleteCmk(user_name);
}

bool KMSInterface::describeCmk(const std::string &user_name, std::string &result, bool decrypt) {
    return instance_ && instance_->describeCmk(user_name, result, decrypt);
}

bool KMSInterface::rotateCmkNow(const std::string& user_name) {
    return instance_ && instance_->rotateCmkNow(user_name);
}

bool KMSInterface::handleAutoRotateCmd(std::string* action, const std::string& user_name) {
    return instance_ && instance_->handleAutoRotateCmd(action, user_name);
}

bool KMSInterface::getCmkAutoRotateStatusByUsername(const std::string& user_name) {
    return instance_ && instance_->getCmkAutoRotateStatusByUsername(user_name);
}

bool KMSInterface::encryptData(std::string& dek) {
    return instance_ && instance_->encryptData(dek);
}

bool KMSInterface::decryptData(std::string& dek) {
    return instance_ && instance_->decryptData(dek);
}

bool KMSInterface::createDek(std::string &col_dek, const std::string &column_name){
    return instance_ && instance_->createDek(col_dek, column_name);
}