#ifndef NETWORK_NIC_CONGESTION_CONTROL_H
#define NETWORK_NIC_CONGESTION_CONTROL_H

#include <cstdint>
#include "core/time.h"
#include "core/types.h"
#include "network/packet.h"

namespace dofs {

class CongestionControl {
public:
        explicit CongestionControl(Bytes init_cwnd, Bytes max_cwnd) noexcept;
        virtual ~CongestionControl() = default;

        virtual void update(const Packet& pkt, Time rtt) noexcept = 0;

        virtual bool is_allowed_to_send(Bytes bytes_outstanding,
                                        Bytes next_bytes) const noexcept;

        Bytes cwnd() const noexcept {
                return _cwnd;
        }
        Bytes cwnd_max() const noexcept {
                return _cwnd_max;
        }

protected:
        Bytes _cwnd;
        Bytes _cwnd_max;
};

class DCQCN final : public CongestionControl {
public:
        explicit DCQCN(Bytes init_cwnd, Bytes max_cwnd) noexcept;
        virtual void update(const Packet& pkt, Time rtt) noexcept override;
};

class NSCC final : public CongestionControl {
public:
        explicit NSCC(Bytes init_cwnd, Bytes max_cwnd) noexcept;
        virtual void update(const Packet& pkt, Time rtt) noexcept override;
};

} // namespace dofs

#endif // NETWORK_NIC_CONGESTION_CONTROL_H
