#pragma once

#include <chrono>
#include <cstdint>
#include <random>

#include "behavior/tasks/types.hpp"
#include "utils/crypto/rsa/RsaPublicKey.hpp"


/**
 * Contains common information about a certain peer.
 * All the information contained here are "public": they can be communicated to anybody else safely.
 */
class Peer {
public:
    Peer();
    explicit Peer(const drp::util::crypto::RsaPublicKey& cryptoRsaPublicKey);
    explicit Peer(
        std::uint32_t id,
        bool serverEnabled,
        drp::task::TaskType status,
        std::uint8_t channel,
        const std::chrono::high_resolution_clock::duration& latencyAverage,
        const drp::util::crypto::RsaPublicKey& cryptoRsaPublicKey
    );

    [[nodiscard]] std::vector<std::uint8_t> serialize() const;
    static Peer deserialize(std::vector<std::uint8_t> &data);

    // identification
    std::uint32_t id {};  // TODO(Faraphel): shall be removed in the future

    // network
    bool serverEnabled {};
    drp::task::TaskType status {};
    std::uint8_t channel {};
    std::chrono::high_resolution_clock::duration latencyAverage {};

    // cryptography
    drp::util::crypto::RsaPublicKey cryptoRsaPublicKey {};

private:
    // random
    static std::mt19937 randomGenerator;
    static std::uniform_int_distribution<std::uint32_t> randomDistribution;
};
