#pragma once

#include <string>
#include <vector>
#include <random>
#include <sstream>
#include <iomanip>
#include <memory>
#include <mutex>

namespace node669427 {

class CryptoEngine {
public:
    CryptoEngine();
    ~CryptoEngine();

    bool loadKey(const std::string& key_path);
    bool loadKeyFromBuffer(const std::string& key_data);

    std::string hmacSha256(const std::string& data) const;
    static std::string hmacSha256(const std::string& key, const std::string& data);
    static std::string sha256(const std::string& data);
    static std::string generateNonce(size_t len = 16);
    static std::string base64Encode(const std::string& data);
    static std::string base64Decode(const std::string& data);
    static std::string bytesToHex(const std::vector<uint8_t>& bytes);
    static std::vector<uint8_t> hexToBytes(const std::string& hex);

    bool verifySignature(const std::string& data, const std::string& signature) const;
    std::string signRequest(const std::string& timestamp, const std::string& nonce, const std::string& method, const std::string& path, const std::string& payload) const;

private:
    std::string hmac_key_;
    mutable std::mutex key_mutex_;
};

} // namespace node669427
