#ifndef DEVICE_CTRL_CRYPTO_H
#define DEVICE_CTRL_CRYPTO_H
#include <iomanip>
#include <ios>
#include <sstream>
#include <string>
#include <openssl/hmac.h>
#include <openssl/sha.h>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/buffer.h>

#include "base64_util.h"

namespace zsy::CryptoUtil
{
    inline std::string sha1(const std::string &data)
    {
        unsigned char digest[SHA_DIGEST_LENGTH];
        SHA1(reinterpret_cast<const unsigned char *>(data.c_str()), data.size(), digest);

        std::ostringstream out;
        out << std::hex << std::setfill('0');
        for (unsigned char c: digest)
        {
            out << std::setw(2) << static_cast<int>(c);
        }
        return out.str();
    }

    inline std::string hmacSha1(const std::string &key, const std::string &data)
    {
        unsigned char digest[EVP_MAX_MD_SIZE];

        unsigned int digest_len = 0;

        // 计算HMAC-SHA1
        const unsigned char *digest_ptr = HMAC(
            EVP_sha1(),
            key.c_str(),
            static_cast<int>(key.length()),
            reinterpret_cast<const unsigned char *>(data.c_str()),
            data.length(),
            digest,
            &digest_len
        );

        if (!digest_ptr)
        {
            throw std::runtime_error("HMAC-SHA1 计算失败");
        }

        return Base64::encode(digest, digest_len);
    }
}
#endif // DEVICE_CTRL_CRYPTO_H