use serde::{Deserialize, Serialize};
use std::net::Ipv4Addr;

/// This represents one of several Message options that takes a list of Ipv4Addr values.
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
pub struct AddressListOption(Vec<Ipv4Addr>);

impl AddressListOption {
    /// Create an `AddressList` directly from a `Vec<Ipv4Addr>`.
    pub fn new(list: Vec<Ipv4Addr>) -> Self {
        Self(list)
    }

    /// Used, when serializing, to add to the byte buffer.
    #[inline]
    pub fn extend_into(&self, bytes: &mut Vec<u8>, tag: u8) {
        bytes.push(tag); // tag
        bytes.push((self.0.len() * 4) as u8); // length, multiples of 4, min 4
        self.0
            .iter()
            .for_each(|ip| bytes.extend_from_slice(&ip.octets())); // value
    }

    /// Get the `Vec<Ipv4Addr>` this type wraps.
    pub fn inner(self) -> Vec<Ipv4Addr> {
        self.0
    }
}

impl From<AddressListOption> for String {
    fn from(val: AddressListOption) -> Self {
        format!("{:?}", val.0)
    }
}

impl From<&[u8]> for AddressListOption {
    fn from(value: &[u8]) -> Self {
        Self(
            value
                .chunks(4)
                .map(|chunk| Ipv4Addr::new(chunk[0], chunk[1], chunk[2], chunk[3]))
                .collect(),
        )
    }
}
