#ifndef GENERATOR_NODE_HPP_
#define GENERATOR_NODE_HPP_

#include <cstdint>

/**
 * @brief A generator node with a specific seed.
 */
class GeneratorNode
{
public:
    /**
     * @brief The type representing seeds, keys and values.
     */
    typedef uint64_t ID;

private:
    /**
     * @brief Permute an ID.
     */
    ID permute(ID id);

    /**
     * @brief Get the value for a given key.
     * 
     * @param key The key.
     * @return The value.
     */
    ID getValue(ID key);

public:
    /**
     * @brief The seed for this node.
     */
    ID seed;

    /**
     * @brief Construct a generator node.
     * 
     * @param seed The seed.
     */
    GeneratorNode(ID seed = 0);

    GeneratorNode(const GeneratorNode &node);
    GeneratorNode(GeneratorNode &&node);

    /**
     * @brief Get the value for a given key and the current seed.
     * 
     * @param key The key.
     * @return The value for that key.
     */
    ID operator[](ID key);

    GeneratorNode& operator=(GeneratorNode other);

    /**
     * @brief Get a generator node seeded with the value of the key.
     * 
     * @param key The key.
     * @return The new generator node. 
     */
    GeneratorNode operator()(ID key);

    template<typename... TArgs>
    GeneratorNode operator()(ID a, TArgs... args)
    {
        return GeneratorNode(permute(a))(args...);
    }
};

#endif