use serde::{Deserialize, Serialize};

#[derive(Clone, Debug, PartialEq, Eq)]
pub struct ASIdentifiers {
    pub asn: Vec<ASIdentifierChoice>
}




// ASN
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ASIdentifierChoice {
    Inherit,
    ASIDsOrRanges(Vec<ASIDOrRange>),
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub enum ASIDOrRange {
    Id(Asn),
    AsRange(ASRange),
}


#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ASRange {
    pub min: Asn,
    pub max: Asn,
}

impl ASRange {
    /// Creates a new AS number range from the smallest and largest number.
    pub fn new(min: Asn, max: Asn) -> Self {
        ASRange { min, max }
    }

    /// Returns an AS block covering all ASNs.
    pub fn all() -> ASRange {
        ASRange::new(Asn::MIN, Asn::MAX)
    }

    /// Returns the smallest AS number that is part of this range.
    pub fn min(self) -> Asn {
        self.min
    }

    /// Returns the largest AS number that is still part of this range.
    pub fn max(self) -> Asn {
        self.max
    }

    /// Returns the number of ASNs covered by this value.
    pub fn asn_count(self) -> u32 {
        u32::from(self.max) - u32::from(self.min) + 1
    }
}

#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Default, Serialize, Deserialize)]
pub struct Asn(u32);

impl Asn {
    pub const MIN: Asn = Asn(u32::MIN);
    pub const MAX: Asn = Asn(u32::MAX);

    /// Creates an AS number from a `u32`.
    pub fn from_u32(value: u32) -> Self {
        Asn(value)
    }

    /// Converts an AS number into a `u32`.
    pub fn into_u32(self) -> u32 {
        self.0
    }

    /// Converts an AS number into a network-order byte array.
    pub fn to_raw(self) -> [u8; 4] {
        self.0.to_be_bytes()
    }
}

impl From<u32> for Asn {
    fn from(id: u32) -> Self {
        Asn(id)
    }
}

impl From<Asn> for u32 {
    fn from(id: Asn) -> Self {
        id.0
    }
}