#pragma once

#include <cstdint>
#include <cstddef>
#include <string>
#include <vector>
#include <map>
#include <mutex>

namespace paritypp {

// Client credential: name + shared secret key
struct auth_credential {
    std::string client_name;
    std::vector<uint8_t> key; // Shared secret (used for HMAC-SHA256)
};

// Authentication store: manages client credentials
class auth_store {
public:
    // Add/update a client credential
    void add_client(const std::string& name, const std::vector<uint8_t>& key);
    void add_client(const std::string& name, const std::string& key_str);

    // Remove a client
    bool remove_client(const std::string& name);

    // Lookup client key (returns empty if not found)
    bool lookup(const std::string& name, std::vector<uint8_t>& key_out) const;

    // Check if a client exists
    bool has_client(const std::string& name) const;

    // Get all client names
    std::vector<std::string> list_clients() const;

private:
    mutable std::mutex mutex_;
    std::map<std::string, std::vector<uint8_t>> clients_; // name -> key
};

// Authentication helper functions
struct auth {
    // Generate a random nonce for challenge-response
    static std::vector<uint8_t> generate_nonce(size_t len = 32);

    // Compute HMAC-SHA256(key, data) for auth verification
    static std::vector<uint8_t> compute_hmac(const std::vector<uint8_t>& key,
                                              const std::vector<uint8_t>& data);

    // Verify HMAC response
    static bool verify_hmac(const std::vector<uint8_t>& key,
                            const std::vector<uint8_t>& data,
                            const std::vector<uint8_t>& expected_hmac);

    static constexpr size_t NONCE_SIZE = 32;
    static constexpr size_t HMAC_SIZE = 32; // SHA-256 output
};

} // namespace paritypp
