pub mod decoder;
pub mod encoder;
pub mod frame;

pub use frame::{ErrorCode, Frame, MessageType};

use frame::HeaderLimits;

/// Length-delimited codec for the TCP wire protocol.
///
/// The `headers_enabled` flag is set after the Connect/ConnectAck handshake
/// when both client and server advertise `CAP_HEADERS`. It controls whether
/// Publish, Deliver, and FetchResponse frames include header sections.
///
/// The `ttl_enabled` flag is set when both sides advertise `CAP_MESSAGE_TTL`.
/// It controls whether Publish, Deliver, and FetchResponse frames include
/// the `ttl_ms` field.
///
/// When `headers_enabled` is true, the codec validates incoming Publish
/// headers against `header_limits` during decode (defense in depth).
#[derive(Debug)]
pub struct MessageCodec {
    max_frame_size: u32,
    headers_enabled: bool,
    ttl_enabled: bool,
    header_limits: HeaderLimits,
}

impl MessageCodec {
    pub fn new(max_frame_size: u32) -> Self {
        Self {
            max_frame_size,
            headers_enabled: false,
            ttl_enabled: false,
            header_limits: HeaderLimits::default(),
        }
    }

    /// Enable header encoding/decoding on this codec.
    /// Called after capability negotiation determines both sides support headers.
    pub fn set_headers_enabled(&mut self, enabled: bool) {
        self.headers_enabled = enabled;
    }

    /// Returns whether headers are enabled on this codec.
    pub fn headers_enabled(&self) -> bool {
        self.headers_enabled
    }

    /// Enable TTL encoding/decoding on this codec.
    /// Called after capability negotiation determines both sides support message TTL.
    pub fn set_ttl_enabled(&mut self, enabled: bool) {
        self.ttl_enabled = enabled;
    }

    /// Returns whether TTL is enabled on this codec.
    pub fn ttl_enabled(&self) -> bool {
        self.ttl_enabled
    }

    /// Set header validation limits on this codec.
    /// Called during connection setup to propagate config limits.
    pub fn set_header_limits(&mut self, limits: HeaderLimits) {
        self.header_limits = limits;
    }
}
