#ifndef C_TOXCORE_TESTING_SUPPORT_DOUBLES_FAKE_RANDOM_H
#define C_TOXCORE_TESTING_SUPPORT_DOUBLES_FAKE_RANDOM_H

#include <cstddef>
#include <functional>
#include <random>

#include "../public/random.hh"

// Forward declaration
struct Random;

namespace tox::test {

class FakeRandom : public RandomSystem {
public:
    using EntropySource = std::function<void(uint8_t *_Nonnull out, std::size_t count)>;
    using Observer = std::function<void(const uint8_t *_Nonnull data, std::size_t count)>;

    explicit FakeRandom(uint64_t seed);

    uint32_t uniform(uint32_t upper_bound) override;
    void bytes(uint8_t *_Nonnull out, std::size_t count) override;

    /**
     * @brief Set a custom entropy source.
     * If set, this function will be called to generate random bytes instead of the PRNG.
     */
    void set_entropy_source(EntropySource source);

    /**
     * @brief Set an observer to record generated bytes.
     */
    void set_observer(Observer observer);

    /**
     * @brief Returns C-compatible Random struct.
     */
    struct Random c_random() override;

private:
    std::minstd_rand rng_;
    EntropySource entropy_source_;
    Observer observer_;
};

}  // namespace tox::test

#endif  // C_TOXCORE_TESTING_SUPPORT_DOUBLES_FAKE_RANDOM_H
