use std::net::SocketAddrV4;

/// All configuration for a `Socket`.
#[derive(Debug)]
#[cfg_attr(
    feature = "v4_server",
    derive(serde::Serialize, serde::Deserialize),
    serde(default = "SocketConfig::default_server")
)]
#[cfg_attr(feature = "v4_client", derive(clap::Args))]
pub struct SocketConfig {
    /// The socket will bind to this address and port when calling `Socket::new`.
    #[cfg_attr(feature = "v4_client", arg(long, default_value_t = Self::default_client().listen_address))]
    pub listen_address: SocketAddrV4,
    /// The name of the network interface to broadcast to.
    /// Currently only takes one interface.
    #[cfg_attr(feature = "v4_client", arg(long))]
    pub interface: Option<String>,
}

impl SocketConfig {
    /// Similar to a `Default` impl, but specifically for use with `Server`.
    /// Uses the `RESOLVED_SERVER_PORT`.
    #[cfg(feature = "v4_server")]
    pub fn default_server() -> Self {
        use std::net::Ipv4Addr;

        SocketConfig {
            listen_address: SocketAddrV4::new(
                Ipv4Addr::new(0, 0, 0, 0),
                crate::v4::RESOLVED_SERVER_PORT,
            ),
            interface: None,
        }
    }

    /// Similar to a `Default` impl, but specifically for use with `Client`.
    /// Uses the `RESOLVED_CLIENT_PORT`.
    #[cfg(feature = "v4_client")]
    pub fn default_client() -> Self {
        use std::net::Ipv4Addr;

        SocketConfig {
            listen_address: SocketAddrV4::new(
                Ipv4Addr::new(0, 0, 0, 0),
                crate::v4::RESOLVED_CLIENT_PORT,
            ),
            interface: None,
        }
    }
}
