#ifndef PASSWORD_HASH_HPP_
#define PASSWORD_HASH_HPP_

#include <cinttypes>
#include <string>

enum class PasswordHashType : uint8_t
{
    Invalid = 0,
    Scrypt = 1,
};

/**
 * @brief Binary representation of different types of password hashes.
 */
union PasswordHash
{
    /**
     * @brief The type of hash used.
     * 
     * This field is common to all variants and decides which variant is used.
     */
    PasswordHashType type;

    /**
     * @brief Ensures that all variants are 256 bytes long.
     * 
     * You must zero out all unused space for future compatibility.
     */
    char padding[256];

    // If type == PasswordHashType::Scrypt
    struct
    {
        PasswordHashType type;
        uint8_t salt[64];
        uint8_t digest[64];
    } scrypt;

    /**
     * @brief Construct an empty (invalid) hash.
     */
    PasswordHash();

    /**
     * @brief Zero out the hash before releasing memory to avoid leak.
     */
    ~PasswordHash();

    /**
     * @brief Set this hash to the specified password.
     * 
     * This automatically generates the salt and chooses the hashing algorithm.
     * 
     * @param password The password.
     */
    PasswordHash& operator=(std::string password);

    /**
     * @brief Return true if this hash matches the specified password.
     */
    bool operator==(std::string password);
};

#endif