use std::cmp::{min, max};
use std::cmp::Ordering::{Less, Equal};
use std::convert::From;
use std::error::Error;
use std::fmt;
use std::iter::FusedIterator;
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
use std::option::Option::{Some, None};

use crate::ipext::{IpAdd, IpSub, IpStep, IpAddrRange, Ipv4AddrRange, Ipv6AddrRange};
use crate::mask::{ip_mask_to_prefix, ipv4_mask_to_prefix, ipv6_mask_to_prefix};

/// An IP network address, either IPv4 or IPv6.
///
/// This enum can contain either an [`Ipv4Net`] or an [`Ipv6Net`]. A
/// [`From`] implementation is provided to convert these into an
/// `IpNet`.
///
/// # Textual representation
///
/// `IpNet` provides a [`FromStr`] implementation for parsing network
/// addresses represented in CIDR notation. See [IETF RFC 4632] for the
/// CIDR notation.
///
/// [`Ipv4Net`]: struct.Ipv4Net.html
/// [`Ipv6Net`]: struct.Ipv6Net.html
/// [`From`]: https://doc.rust-lang.org/std/convert/trait.From.html
/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
///
/// # Examples
///
/// ```
/// use std::net::IpAddr;
/// use ipnet::IpNet;
///
/// let net: IpNet = "10.1.1.0/24".parse().unwrap();
/// assert_eq!(Ok(net.network()), "10.1.1.0".parse());
///
/// let net: IpNet = "fd00::/32".parse().unwrap();
/// assert_eq!(Ok(net.network()), "fd00::".parse());
/// ```
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum IpNet {
    V4(Ipv4Net),
    V6(Ipv6Net),
}

/// An IPv4 network address.
///
/// See [`IpNet`] for a type encompassing both IPv4 and IPv6 network
/// addresses.
///
/// # Textual representation
///
/// `Ipv4Net` provides a [`FromStr`] implementation for parsing network
/// addresses represented in CIDR notation. See [IETF RFC 4632] for the
/// CIDR notation.
///
/// [`IpNet`]: enum.IpNet.html
/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
///
/// # Examples
///
/// ```
/// use std::net::Ipv4Addr;
/// use ipnet::Ipv4Net;
///
/// let net: Ipv4Net = "10.1.1.0/24".parse().unwrap();
/// assert_eq!(Ok(net.network()), "10.1.1.0".parse());
/// ```
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Ipv4Net {
    addr: Ipv4Addr,
    prefix_len: u8,
}

/// An IPv6 network address.
///
/// See [`IpNet`] for a type encompassing both IPv4 and IPv6 network
/// addresses.
///
/// # Textual representation
///
/// `Ipv6Net` provides a [`FromStr`] implementation for parsing network
/// addresses represented in CIDR notation. See [IETF RFC 4632] for the
/// CIDR notation.
///
/// [`IpNet`]: enum.IpNet.html
/// [`FromStr`]: https://doc.rust-lang.org/std/str/trait.FromStr.html
/// [IETF RFC 4632]: https://tools.ietf.org/html/rfc4632
///
/// # Examples
///
/// ```
/// use std::net::Ipv6Addr;
/// use ipnet::Ipv6Net;
///
/// let net: Ipv6Net = "fd00::/32".parse().unwrap();
/// assert_eq!(Ok(net.network()), "fd00::".parse());
/// ```
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct Ipv6Net {
    addr: Ipv6Addr,
    prefix_len: u8,
}

/// An error which can be returned when the prefix length is invalid.
///
/// Valid prefix lengths are 0 to 32 for IPv4 and 0 to 128 for IPv6.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PrefixLenError;

impl fmt::Display for PrefixLenError {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.write_str("invalid IP prefix length")
    }
}

impl Error for PrefixLenError {}

impl IpNet {
    /// Creates a new IP network address from an `IpAddr` and prefix
    /// length.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::Ipv6Addr;
    /// use ipnet::{IpNet, PrefixLenError};
    ///
    /// let net = IpNet::new(Ipv6Addr::LOCALHOST.into(), 48);
    /// assert!(net.is_ok());
    /// 
    /// let bad_prefix_len = IpNet::new(Ipv6Addr::LOCALHOST.into(), 129);
    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
    /// ```
    pub fn new(ip: IpAddr, prefix_len: u8) -> Result<IpNet, PrefixLenError> {
        Ok(match ip {
            IpAddr::V4(a) => Ipv4Net::new(a, prefix_len)?.into(),
            IpAddr::V6(a) => Ipv6Net::new(a, prefix_len)?.into(),
        })
    }

    /// Creates a new IP network address from an `IpAddr` and netmask.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::Ipv6Addr;
    /// use ipnet::{IpNet, PrefixLenError};
    ///
    /// let net = IpNet::with_netmask(Ipv6Addr::LOCALHOST.into(), Ipv6Addr::from(0xffff_ffff_ffff_0000_0000_0000_0000_0000).into());
    /// assert!(net.is_ok());
    ///
    /// let bad_prefix_len = IpNet::with_netmask(Ipv6Addr::LOCALHOST.into(), Ipv6Addr::from(0xffff_ffff_ffff_0000_0001_0000_0000_0000).into());
    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
    /// ```
    pub fn with_netmask(ip: IpAddr, netmask: IpAddr) -> Result<IpNet, PrefixLenError> {
        let prefix = ip_mask_to_prefix(netmask)?;
        Self::new(ip, prefix)
    }

    /// Returns a copy of the network with the address truncated to the
    /// prefix length.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::IpNet;
    /// #
    /// assert_eq!(
    ///     "192.168.12.34/16".parse::<IpNet>().unwrap().trunc(),
    ///     "192.168.0.0/16".parse().unwrap()
    /// );
    ///
    /// assert_eq!(
    ///     "fd00::1:2:3:4/16".parse::<IpNet>().unwrap().trunc(),
    ///     "fd00::/16".parse().unwrap()
    /// );
    /// ```
    pub fn trunc(&self) -> IpNet {
        match *self {
            IpNet::V4(ref a) => IpNet::V4(a.trunc()),
            IpNet::V6(ref a) => IpNet::V6(a.trunc()),
        }
    }

    /// Returns the address.
    pub fn addr(&self) -> IpAddr {
        match *self {
            IpNet::V4(ref a) => IpAddr::V4(a.addr),
            IpNet::V6(ref a) => IpAddr::V6(a.addr),
        }
    }

    /// Returns the prefix length.
    pub fn prefix_len(&self) -> u8 {
        match *self {
            IpNet::V4(ref a) => a.prefix_len(),
            IpNet::V6(ref a) => a.prefix_len(),
        }
    }

    /// Returns the maximum valid prefix length.
    pub fn max_prefix_len(&self) -> u8 {
        match *self {
            IpNet::V4(ref a) => a.max_prefix_len(),
            IpNet::V6(ref a) => a.max_prefix_len(),
        }
    }

    /// Returns the network mask.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::IpAddr;
    /// # use ipnet::IpNet;
    /// #
    /// let net: IpNet = "10.1.0.0/20".parse().unwrap();
    /// assert_eq!(Ok(net.netmask()), "255.255.240.0".parse());
    ///
    /// let net: IpNet = "fd00::/24".parse().unwrap();
    /// assert_eq!(Ok(net.netmask()), "ffff:ff00::".parse());
    /// ```
    pub fn netmask(&self) -> IpAddr {
        match *self {
            IpNet::V4(ref a) => IpAddr::V4(a.netmask()),
            IpNet::V6(ref a) => IpAddr::V6(a.netmask()),
        }
    }

    /// Returns the host mask.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::IpAddr;
    /// # use ipnet::IpNet;
    /// #
    /// let net: IpNet = "10.1.0.0/20".parse().unwrap();
    /// assert_eq!(Ok(net.hostmask()), "0.0.15.255".parse());
    ///
    /// let net: IpNet = "fd00::/24".parse().unwrap();
    /// assert_eq!(Ok(net.hostmask()), "::ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
    /// ```
    pub fn hostmask(&self) -> IpAddr {
        match *self {
            IpNet::V4(ref a) => IpAddr::V4(a.hostmask()),
            IpNet::V6(ref a) => IpAddr::V6(a.hostmask()),
        }
    }
    
    /// Returns the network address.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::IpAddr;
    /// # use ipnet::IpNet;
    /// #
    /// let net: IpNet = "172.16.123.123/16".parse().unwrap();
    /// assert_eq!(Ok(net.network()), "172.16.0.0".parse());
    ///
    /// let net: IpNet = "fd00:1234:5678::/24".parse().unwrap();
    /// assert_eq!(Ok(net.network()), "fd00:1200::".parse());
    /// ```
    pub fn network(&self) -> IpAddr {
        match *self {
            IpNet::V4(ref a) => IpAddr::V4(a.network()),
            IpNet::V6(ref a) => IpAddr::V6(a.network()),
        }
    }    
    
    /// Returns the broadcast address.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::IpAddr;
    /// # use ipnet::IpNet;
    /// #
    /// let net: IpNet = "172.16.0.0/22".parse().unwrap();
    /// assert_eq!(Ok(net.broadcast()), "172.16.3.255".parse());
    ///
    /// let net: IpNet = "fd00:1234:5678::/24".parse().unwrap();
    /// assert_eq!(Ok(net.broadcast()), "fd00:12ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
    /// ```
    pub fn broadcast(&self) -> IpAddr {
        match *self {
            IpNet::V4(ref a) => IpAddr::V4(a.broadcast()),
            IpNet::V6(ref a) => IpAddr::V6(a.broadcast()),
        }
    }
    
    /// Returns the `IpNet` that contains this one.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::IpNet;
    /// #
    /// let n1: IpNet = "172.16.1.0/24".parse().unwrap();
    /// let n2: IpNet = "172.16.0.0/23".parse().unwrap();
    /// let n3: IpNet = "172.16.0.0/0".parse().unwrap();
    ///
    /// assert_eq!(n1.supernet().unwrap(), n2);
    /// assert_eq!(n3.supernet(), None);
    ///
    /// let n1: IpNet = "fd00:ff00::/24".parse().unwrap();
    /// let n2: IpNet = "fd00:fe00::/23".parse().unwrap();
    /// let n3: IpNet = "fd00:fe00::/0".parse().unwrap();
    ///
    /// assert_eq!(n1.supernet().unwrap(), n2);
    /// assert_eq!(n3.supernet(), None);
    /// ```
    pub fn supernet(&self) -> Option<IpNet> {
        match *self {
            IpNet::V4(ref a) => a.supernet().map(IpNet::V4),
            IpNet::V6(ref a) => a.supernet().map(IpNet::V6),
        }
    }

    /// Returns `true` if this network and the given network are 
    /// children of the same supernet.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::IpNet;
    /// #
    /// let n4_1: IpNet = "10.1.0.0/24".parse().unwrap();
    /// let n4_2: IpNet = "10.1.1.0/24".parse().unwrap();
    /// let n4_3: IpNet = "10.1.2.0/24".parse().unwrap();
    /// let n6_1: IpNet = "fd00::/18".parse().unwrap();
    /// let n6_2: IpNet = "fd00:4000::/18".parse().unwrap();
    /// let n6_3: IpNet = "fd00:8000::/18".parse().unwrap();
    ///
    /// assert!( n4_1.is_sibling(&n4_2));
    /// assert!(!n4_2.is_sibling(&n4_3));
    /// assert!( n6_1.is_sibling(&n6_2));
    /// assert!(!n6_2.is_sibling(&n6_3));
    /// assert!(!n4_1.is_sibling(&n6_2));
    /// ```
    pub fn is_sibling(&self, other: &IpNet) -> bool {
        match (*self, *other) {
            (IpNet::V4(ref a), IpNet::V4(ref b)) => a.is_sibling(b),
            (IpNet::V6(ref a), IpNet::V6(ref b)) => a.is_sibling(b),
            _ => false,
        }
    }

    /// Return an `Iterator` over the host addresses in this network.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::IpAddr;
    /// # use ipnet::IpNet;
    /// #
    /// let net: IpNet = "10.0.0.0/30".parse().unwrap();
    /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
    ///     "10.0.0.1".parse::<IpAddr>().unwrap(),
    ///     "10.0.0.2".parse().unwrap(),
    /// ]);
    ///
    /// let net: IpNet = "10.0.0.0/31".parse().unwrap();
    /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
    ///     "10.0.0.0".parse::<IpAddr>().unwrap(),
    ///     "10.0.0.1".parse().unwrap(),
    /// ]);
    ///
    /// let net: IpNet = "fd00::/126".parse().unwrap();
    /// assert_eq!(net.hosts().collect::<Vec<IpAddr>>(), vec![
    ///     "fd00::".parse::<IpAddr>().unwrap(),
    ///     "fd00::1".parse().unwrap(),
    ///     "fd00::2".parse().unwrap(),
    ///     "fd00::3".parse().unwrap(),
    /// ]);
    /// ```
    pub fn hosts(&self) -> IpAddrRange {
        match *self {
            IpNet::V4(ref a) => IpAddrRange::V4(a.hosts()),
            IpNet::V6(ref a) => IpAddrRange::V6(a.hosts()),
        }
    }
    
    /// Returns an `Iterator` over the subnets of this network with the
    /// given prefix length.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::{IpNet, PrefixLenError};
    /// #
    /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
    /// assert_eq!(net.subnets(26).unwrap().collect::<Vec<IpNet>>(), vec![
    ///     "10.0.0.0/26".parse::<IpNet>().unwrap(),
    ///     "10.0.0.64/26".parse().unwrap(),
    ///     "10.0.0.128/26".parse().unwrap(),
    ///     "10.0.0.192/26".parse().unwrap(),
    /// ]);
    ///
    /// let net: IpNet = "fd00::/16".parse().unwrap();
    /// assert_eq!(net.subnets(18).unwrap().collect::<Vec<IpNet>>(), vec![
    ///     "fd00::/18".parse::<IpNet>().unwrap(),
    ///     "fd00:4000::/18".parse().unwrap(),
    ///     "fd00:8000::/18".parse().unwrap(),
    ///     "fd00:c000::/18".parse().unwrap(),
    /// ]);
    ///
    /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
    /// assert_eq!(net.subnets(23), Err(PrefixLenError));
    ///
    /// let net: IpNet = "10.0.0.0/24".parse().unwrap();
    /// assert_eq!(net.subnets(33), Err(PrefixLenError));
    ///
    /// let net: IpNet = "fd00::/16".parse().unwrap();
    /// assert_eq!(net.subnets(15), Err(PrefixLenError));
    ///
    /// let net: IpNet = "fd00::/16".parse().unwrap();
    /// assert_eq!(net.subnets(129), Err(PrefixLenError));
    /// ```
    pub fn subnets(&self, new_prefix_len: u8) -> Result<IpSubnets, PrefixLenError> {
        match *self {
            IpNet::V4(ref a) => a.subnets(new_prefix_len).map(IpSubnets::V4),
            IpNet::V6(ref a) => a.subnets(new_prefix_len).map(IpSubnets::V6),
        }
    }

    /// Test if a network address contains either another network
    /// address or an IP address.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::IpAddr;
    /// # use ipnet::IpNet;
    /// #
    /// let net4: IpNet = "192.168.0.0/24".parse().unwrap();
    /// let net4_yes: IpNet = "192.168.0.0/25".parse().unwrap();
    /// let net4_no: IpNet = "192.168.0.0/23".parse().unwrap();
    /// let ip4_yes: IpAddr = "192.168.0.1".parse().unwrap();
    /// let ip4_no: IpAddr = "192.168.1.0".parse().unwrap();
    ///
    /// assert!(net4.contains(&net4));
    /// assert!(net4.contains(&net4_yes));
    /// assert!(!net4.contains(&net4_no));
    /// assert!(net4.contains(&ip4_yes));
    /// assert!(!net4.contains(&ip4_no));
    ///
    ///
    /// let net6: IpNet = "fd00::/16".parse().unwrap();
    /// let net6_yes: IpNet = "fd00::/17".parse().unwrap();
    /// let net6_no: IpNet = "fd00::/15".parse().unwrap();
    /// let ip6_yes: IpAddr = "fd00::1".parse().unwrap();
    /// let ip6_no: IpAddr = "fd01::".parse().unwrap();
    ///
    /// assert!(net6.contains(&net6));
    /// assert!(net6.contains(&net6_yes));
    /// assert!(!net6.contains(&net6_no));
    /// assert!(net6.contains(&ip6_yes));
    /// assert!(!net6.contains(&ip6_no));
    ///
    /// assert!(!net4.contains(&net6));
    /// assert!(!net6.contains(&net4));
    /// assert!(!net4.contains(&ip6_no));
    /// assert!(!net6.contains(&ip4_no));
    /// ```
    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
        Contains::contains(self, other)
    }

    /// Aggregate a `Vec` of `IpNet`s and return the result as a new
    /// `Vec`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::IpNet;
    /// #
    /// let nets = vec![
    ///     "10.0.0.0/24".parse::<IpNet>().unwrap(),
    ///     "10.0.1.0/24".parse().unwrap(),
    ///     "10.0.2.0/24".parse().unwrap(),
    ///     "fd00::/18".parse().unwrap(),
    ///     "fd00:4000::/18".parse().unwrap(),
    ///     "fd00:8000::/18".parse().unwrap(),
    /// ];
    ///
    /// assert_eq!(IpNet::aggregate(&nets), vec![
    ///     "10.0.0.0/23".parse::<IpNet>().unwrap(),
    ///     "10.0.2.0/24".parse().unwrap(),
    ///     "fd00::/17".parse().unwrap(),
    ///     "fd00:8000::/18".parse().unwrap(),
    /// ]);
    /// ```
    pub fn aggregate(networks: &Vec<IpNet>) -> Vec<IpNet> {
        // It's 2.5x faster to split the input up and run them using the
        // specific IPv4 and IPV6 implementations. merge_intervals() and
        // the comparisons are much faster running over integers.
        let mut ipv4nets: Vec<Ipv4Net> = Vec::new();
        let mut ipv6nets: Vec<Ipv6Net> = Vec::new();

        for n in networks {
            match *n {
                IpNet::V4(x) => ipv4nets.push(x),
                IpNet::V6(x) => ipv6nets.push(x),
            }
        }

        let mut res: Vec<IpNet> = Vec::new();
        let ipv4aggs = Ipv4Net::aggregate(&ipv4nets);
        let ipv6aggs = Ipv6Net::aggregate(&ipv6nets);
        res.extend::<Vec<IpNet>>(ipv4aggs.into_iter().map(IpNet::V4).collect::<Vec<IpNet>>());
        res.extend::<Vec<IpNet>>(ipv6aggs.into_iter().map(IpNet::V6).collect::<Vec<IpNet>>());
        res
    }
}

impl Default for IpNet {
    fn default() -> Self {
        Self::V4(Ipv4Net::default())
    }
}

impl fmt::Debug for IpNet {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(self, fmt)
    }
}

impl fmt::Display for IpNet {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            IpNet::V4(ref a) => a.fmt(fmt),
            IpNet::V6(ref a) => a.fmt(fmt),
        }
    }
}

impl From<Ipv4Net> for IpNet {
    fn from(net: Ipv4Net) -> IpNet {
        IpNet::V4(net)
    }
}

impl From<Ipv6Net> for IpNet {
    fn from(net: Ipv6Net) -> IpNet {
        IpNet::V6(net)
    }
}

impl From<IpAddr> for IpNet {
    fn from(addr: IpAddr) -> IpNet {
        match addr {
            IpAddr::V4(a) => IpNet::V4(a.into()),
            IpAddr::V6(a) => IpNet::V6(a.into()),
        }
    }
}

impl Ipv4Net {
    /// Creates a new IPv4 network address from an `Ipv4Addr` and prefix
    /// length.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::Ipv4Addr;
    /// use ipnet::{Ipv4Net, PrefixLenError};
    ///
    /// let net = Ipv4Net::new(Ipv4Addr::new(10, 1, 1, 0), 24);
    /// assert!(net.is_ok());
    ///
    /// let bad_prefix_len = Ipv4Net::new(Ipv4Addr::new(10, 1, 1, 0), 33);
    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
    /// ```
    pub const fn new(ip: Ipv4Addr, prefix_len: u8) -> Result<Ipv4Net, PrefixLenError> {
        if prefix_len > 32 {
            return Err(PrefixLenError);
        }
        Ok(Ipv4Net { addr: ip, prefix_len: prefix_len })
    }

    /// Creates a new IPv4 network address from an `Ipv4Addr` and netmask.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::Ipv4Addr;
    /// use ipnet::{Ipv4Net, PrefixLenError};
    ///
    /// let net = Ipv4Net::with_netmask(Ipv4Addr::new(10, 1, 1, 0), Ipv4Addr::new(255, 255, 255, 0));
    /// assert!(net.is_ok());
    ///
    /// let bad_prefix_len = Ipv4Net::with_netmask(Ipv4Addr::new(10, 1, 1, 0), Ipv4Addr::new(255, 255, 0, 1));
    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
    /// ```
    pub fn with_netmask(ip: Ipv4Addr, netmask: Ipv4Addr) -> Result<Ipv4Net, PrefixLenError> {
        let prefix = ipv4_mask_to_prefix(netmask)?;
        Self::new(ip, prefix)
    }

    /// Returns a copy of the network with the address truncated to the
    /// prefix length.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::Ipv4Net;
    /// #
    /// assert_eq!(
    ///     "192.168.12.34/16".parse::<Ipv4Net>().unwrap().trunc(),
    ///     "192.168.0.0/16".parse().unwrap()
    /// );
    /// ```
    pub fn trunc(&self) -> Ipv4Net {
        Ipv4Net::new(self.network(), self.prefix_len).unwrap()
    }

    /// Returns the address.
    pub const fn addr(&self) -> Ipv4Addr {
        self.addr
    }

    /// Returns the prefix length.
    pub const fn prefix_len(&self) -> u8 {
        self.prefix_len
    }

    /// Returns the maximum valid prefix length.
    pub const fn max_prefix_len(&self) -> u8 {
        32
    }
    
    /// Returns the network mask.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::Ipv4Addr;
    /// # use ipnet::Ipv4Net;
    /// #
    /// let net: Ipv4Net = "10.1.0.0/20".parse().unwrap();
    /// assert_eq!(Ok(net.netmask()), "255.255.240.0".parse());
    /// ```
    pub fn netmask(&self) -> Ipv4Addr {
        Ipv4Addr::from(self.netmask_u32())
    }

    fn netmask_u32(&self) -> u32 {
        u32::max_value().checked_shl(32 - self.prefix_len as u32).unwrap_or(0)
    }

    /// Returns the host mask.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::Ipv4Addr;
    /// # use ipnet::Ipv4Net;
    /// #
    /// let net: Ipv4Net = "10.1.0.0/20".parse().unwrap();
    /// assert_eq!(Ok(net.hostmask()), "0.0.15.255".parse());
    /// ```
    pub fn hostmask(&self) -> Ipv4Addr {
        Ipv4Addr::from(self.hostmask_u32())
    }

    fn hostmask_u32(&self) -> u32 {
        u32::max_value().checked_shr(self.prefix_len as u32).unwrap_or(0)
    }

    /// Returns the network address.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::Ipv4Addr;
    /// # use ipnet::Ipv4Net;
    /// #
    /// let net: Ipv4Net = "172.16.123.123/16".parse().unwrap();
    /// assert_eq!(Ok(net.network()), "172.16.0.0".parse());
    /// ```
    pub fn network(&self) -> Ipv4Addr {
        Ipv4Addr::from(u32::from(self.addr) & self.netmask_u32())
    }

    /// Returns the broadcast address.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::Ipv4Addr;
    /// # use ipnet::Ipv4Net;
    /// #
    /// let net: Ipv4Net = "172.16.0.0/22".parse().unwrap();
    /// assert_eq!(Ok(net.broadcast()), "172.16.3.255".parse());
    /// ```
    pub fn broadcast(&self) -> Ipv4Addr {
        Ipv4Addr::from(u32::from(self.addr) | self.hostmask_u32())
    }

    /// Returns the `Ipv4Net` that contains this one.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::Ipv4Net;
    /// #
    /// let n1: Ipv4Net = "172.16.1.0/24".parse().unwrap();
    /// let n2: Ipv4Net = "172.16.0.0/23".parse().unwrap();
    /// let n3: Ipv4Net = "172.16.0.0/0".parse().unwrap();
    ///
    /// assert_eq!(n1.supernet().unwrap(), n2);
    /// assert_eq!(n3.supernet(), None);
    /// ```
    pub fn supernet(&self) -> Option<Ipv4Net> {
        Ipv4Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok()
    }

    /// Returns `true` if this network and the given network are 
    /// children of the same supernet.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::Ipv4Net;
    /// #
    /// let n1: Ipv4Net = "10.1.0.0/24".parse().unwrap();
    /// let n2: Ipv4Net = "10.1.1.0/24".parse().unwrap();
    /// let n3: Ipv4Net = "10.1.2.0/24".parse().unwrap();
    ///
    /// assert!(n1.is_sibling(&n2));
    /// assert!(!n2.is_sibling(&n3));
    /// ```
    pub fn is_sibling(&self, other: &Ipv4Net) -> bool {
        self.prefix_len > 0 &&
        self.prefix_len == other.prefix_len &&
        self.supernet().unwrap().contains(other)
    }
    
    /// Return an `Iterator` over the host addresses in this network.
    ///
    /// If the prefix length is less than 31 both the network address
    /// and broadcast address are excluded. These are only valid host
    /// addresses when the prefix length is 31.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::Ipv4Addr;
    /// # use ipnet::Ipv4Net;
    /// #
    /// let net: Ipv4Net = "10.0.0.0/30".parse().unwrap();
    /// assert_eq!(net.hosts().collect::<Vec<Ipv4Addr>>(), vec![
    ///     "10.0.0.1".parse::<Ipv4Addr>().unwrap(),
    ///     "10.0.0.2".parse().unwrap(),
    /// ]);
    ///
    /// let net: Ipv4Net = "10.0.0.0/31".parse().unwrap();
    /// assert_eq!(net.hosts().collect::<Vec<Ipv4Addr>>(), vec![
    ///     "10.0.0.0".parse::<Ipv4Addr>().unwrap(),
    ///     "10.0.0.1".parse().unwrap(),
    /// ]);
    /// ```
    pub fn hosts(&self) -> Ipv4AddrRange {
        let mut start = self.network();
        let mut end = self.broadcast();
        
        if self.prefix_len < 31 {
            start = start.saturating_add(1);
            end = end.saturating_sub(1);
        }
        
        Ipv4AddrRange::new(start, end)
    }

    /// Returns an `Iterator` over the subnets of this network with the
    /// given prefix length.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::{Ipv4Net, PrefixLenError};
    /// #
    /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
    /// assert_eq!(net.subnets(26).unwrap().collect::<Vec<Ipv4Net>>(), vec![
    ///     "10.0.0.0/26".parse::<Ipv4Net>().unwrap(),
    ///     "10.0.0.64/26".parse().unwrap(),
    ///     "10.0.0.128/26".parse().unwrap(),
    ///     "10.0.0.192/26".parse().unwrap(),
    /// ]);
    ///
    /// let net: Ipv4Net = "10.0.0.0/30".parse().unwrap();
    /// assert_eq!(net.subnets(32).unwrap().collect::<Vec<Ipv4Net>>(), vec![
    ///     "10.0.0.0/32".parse::<Ipv4Net>().unwrap(),
    ///     "10.0.0.1/32".parse().unwrap(),
    ///     "10.0.0.2/32".parse().unwrap(),
    ///     "10.0.0.3/32".parse().unwrap(),
    /// ]);
    ///
    /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
    /// assert_eq!(net.subnets(23), Err(PrefixLenError));
    ///
    /// let net: Ipv4Net = "10.0.0.0/24".parse().unwrap();
    /// assert_eq!(net.subnets(33), Err(PrefixLenError));
    /// ```
    pub fn subnets(&self, new_prefix_len: u8) -> Result<Ipv4Subnets, PrefixLenError> {
        if self.prefix_len > new_prefix_len || new_prefix_len > 32 {
            return Err(PrefixLenError);
        }
        
        Ok(Ipv4Subnets::new(
            self.network(),
            self.broadcast(),
            new_prefix_len,
        ))
    }

    /// Test if a network address contains either another network
    /// address or an IP address.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::Ipv4Addr;
    /// # use ipnet::Ipv4Net;
    /// #
    /// let net: Ipv4Net = "192.168.0.0/24".parse().unwrap();
    /// let net_yes: Ipv4Net = "192.168.0.0/25".parse().unwrap();
    /// let net_no: Ipv4Net = "192.168.0.0/23".parse().unwrap();
    /// let ip_yes: Ipv4Addr = "192.168.0.1".parse().unwrap();
    /// let ip_no: Ipv4Addr = "192.168.1.0".parse().unwrap();
    ///
    /// assert!(net.contains(&net));
    /// assert!(net.contains(&net_yes));
    /// assert!(!net.contains(&net_no));
    /// assert!(net.contains(&ip_yes));
    /// assert!(!net.contains(&ip_no));
    /// ```
    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
        Contains::contains(self, other)
    }

    // It is significantly faster to work on u32 than Ipv4Addr.
    fn interval(&self) -> (u32, u32) {
        (
            u32::from(self.network()),
            u32::from(self.broadcast()).saturating_add(1),
        )
    }

    /// Aggregate a `Vec` of `Ipv4Net`s and return the result as a new
    /// `Vec`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::Ipv4Net;
    /// #
    /// let nets = vec![
    ///     "10.0.0.0/24".parse::<Ipv4Net>().unwrap(),
    ///     "10.0.1.0/24".parse().unwrap(),
    ///     "10.0.2.0/24".parse().unwrap(),
    /// ];
    ///
    /// assert_eq!(Ipv4Net::aggregate(&nets), vec![
    ///     "10.0.0.0/23".parse::<Ipv4Net>().unwrap(),
    ///     "10.0.2.0/24".parse().unwrap(),
    /// ]);
    pub fn aggregate(networks: &Vec<Ipv4Net>) -> Vec<Ipv4Net> {
        let mut intervals: Vec<(_, _)> = networks.iter().map(|n| n.interval()).collect();
        intervals = merge_intervals(intervals);
        let mut res: Vec<Ipv4Net> = Vec::new();
        
        for (start, mut end) in intervals {
            if end != std::u32::MAX {
                end = end.saturating_sub(1)
            }
            let iter = Ipv4Subnets::new(start.into(), end.into(), 0);
            res.extend(iter);
        }
        res
    }
}

impl Default for Ipv4Net {
    fn default() -> Self {
        Self {
            addr: Ipv4Addr::from(0),
            prefix_len: 0,
        }
    }
}

impl fmt::Debug for Ipv4Net {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(self, fmt)
    }
}

impl fmt::Display for Ipv4Net {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}/{}", self.addr, self.prefix_len)
    }
}

impl From<Ipv4Addr> for Ipv4Net {
    fn from(addr: Ipv4Addr) -> Ipv4Net {
        Ipv4Net { addr, prefix_len: 32 }
    }
}

impl Ipv6Net {    
    /// Creates a new IPv6 network address from an `Ipv6Addr` and prefix
    /// length.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::Ipv6Addr;
    /// use ipnet::{Ipv6Net, PrefixLenError};
    ///
    /// let net = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 24);
    /// assert!(net.is_ok());
    ///
    /// let bad_prefix_len = Ipv6Net::new(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), 129);
    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
    /// ```
    pub const fn new(ip: Ipv6Addr, prefix_len: u8) -> Result<Ipv6Net, PrefixLenError> {
        if prefix_len > 128 {
            return Err(PrefixLenError);
        }
        Ok(Ipv6Net { addr: ip, prefix_len: prefix_len })
    }

    /// Creates a new IPv6 network address from an `Ipv6Addr` and netmask.
    ///
    /// # Examples
    ///
    /// ```
    /// use std::net::Ipv6Addr;
    /// use ipnet::{Ipv6Net, PrefixLenError};
    ///
    /// let net = Ipv6Net::with_netmask(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), Ipv6Addr::from(0xffff_ff00_0000_0000_0000_0000_0000_0000));
    /// assert!(net.is_ok());
    ///
    /// let bad_prefix_len = Ipv6Net::with_netmask(Ipv6Addr::new(0xfd, 0, 0, 0, 0, 0, 0, 0), Ipv6Addr::from(0xffff_ff00_0000_0000_0001_0000_0000_0000));
    /// assert_eq!(bad_prefix_len, Err(PrefixLenError));
    /// ```
    pub fn with_netmask(ip: Ipv6Addr, netmask: Ipv6Addr) -> Result<Ipv6Net, PrefixLenError> {
        let prefix = ipv6_mask_to_prefix(netmask)?;
        Self::new(ip, prefix)
    }

    /// Returns a copy of the network with the address truncated to the
    /// prefix length.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::Ipv6Net;
    /// #
    /// assert_eq!(
    ///     "fd00::1:2:3:4/16".parse::<Ipv6Net>().unwrap().trunc(),
    ///     "fd00::/16".parse().unwrap()
    /// );
    /// ```
    pub fn trunc(&self) -> Ipv6Net {
        Ipv6Net::new(self.network(), self.prefix_len).unwrap()
    }
    
    /// Returns the address.
    pub const fn addr(&self) -> Ipv6Addr {
        self.addr
    }

    /// Returns the prefix length.
    pub const fn prefix_len(&self) -> u8 {
        self.prefix_len
    }
    
    /// Returns the maximum valid prefix length.
    pub const fn max_prefix_len(&self) -> u8 {
        128
    }

    /// Returns the network mask.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::Ipv6Addr;
    /// # use ipnet::Ipv6Net;
    /// #
    /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
    /// assert_eq!(Ok(net.netmask()), "ffff:ff00::".parse());
    /// ```
    pub fn netmask(&self) -> Ipv6Addr {
        self.netmask_u128().into()
    }

    fn netmask_u128(&self) -> u128 {
        u128::max_value().checked_shl((128 - self.prefix_len) as u32).unwrap_or(u128::min_value())
    }

    /// Returns the host mask.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::Ipv6Addr;
    /// # use ipnet::Ipv6Net;
    /// #
    /// let net: Ipv6Net = "fd00::/24".parse().unwrap();
    /// assert_eq!(Ok(net.hostmask()), "::ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
    /// ```
    pub fn hostmask(&self) -> Ipv6Addr {
        self.hostmask_u128().into()
    }

    fn hostmask_u128(&self) -> u128 {
        u128::max_value().checked_shr(self.prefix_len as u32).unwrap_or(u128::min_value())
    }

    /// Returns the network address.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::Ipv6Addr;
    /// # use ipnet::Ipv6Net;
    /// #
    /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
    /// assert_eq!(Ok(net.network()), "fd00:1200::".parse());
    /// ```
    pub fn network(&self) -> Ipv6Addr {
        (u128::from(self.addr) & self.netmask_u128()).into()
    }
    
    /// Returns the last address.
    ///
    /// Technically there is no such thing as a broadcast address for
    /// IPv6. The name is used for consistency with colloquial usage.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::Ipv6Addr;
    /// # use ipnet::Ipv6Net;
    /// #
    /// let net: Ipv6Net = "fd00:1234:5678::/24".parse().unwrap();
    /// assert_eq!(Ok(net.broadcast()), "fd00:12ff:ffff:ffff:ffff:ffff:ffff:ffff".parse());
    /// ```
    pub fn broadcast(&self) -> Ipv6Addr {
        (u128::from(self.addr) | self.hostmask_u128()).into()
    }

    /// Returns the `Ipv6Net` that contains this one.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::str::FromStr;
    /// # use ipnet::Ipv6Net;
    /// #
    /// let n1: Ipv6Net = "fd00:ff00::/24".parse().unwrap();
    /// let n2: Ipv6Net = "fd00:fe00::/23".parse().unwrap();
    /// let n3: Ipv6Net = "fd00:fe00::/0".parse().unwrap();
    ///
    /// assert_eq!(n1.supernet().unwrap(), n2);
    /// assert_eq!(n3.supernet(), None);
    /// ```
    pub fn supernet(&self) -> Option<Ipv6Net> {
        Ipv6Net::new(self.addr, self.prefix_len.wrapping_sub(1)).map(|n| n.trunc()).ok()
    }

    /// Returns `true` if this network and the given network are 
    /// children of the same supernet.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::Ipv6Net;
    /// #
    /// let n1: Ipv6Net = "fd00::/18".parse().unwrap();
    /// let n2: Ipv6Net = "fd00:4000::/18".parse().unwrap();
    /// let n3: Ipv6Net = "fd00:8000::/18".parse().unwrap();
    ///
    /// assert!(n1.is_sibling(&n2));
    /// assert!(!n2.is_sibling(&n3));
    /// ```
    pub fn is_sibling(&self, other: &Ipv6Net) -> bool {
        self.prefix_len > 0 &&
        self.prefix_len == other.prefix_len &&
        self.supernet().unwrap().contains(other)
    }
    
    /// Return an `Iterator` over the host addresses in this network.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::Ipv6Addr;
    /// # use ipnet::Ipv6Net;
    /// #
    /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
    /// assert_eq!(net.hosts().collect::<Vec<Ipv6Addr>>(), vec![
    ///     "fd00::".parse::<Ipv6Addr>().unwrap(),
    ///     "fd00::1".parse().unwrap(),
    ///     "fd00::2".parse().unwrap(),
    ///     "fd00::3".parse().unwrap(),
    /// ]);
    /// ```
    pub fn hosts(&self) -> Ipv6AddrRange {
        Ipv6AddrRange::new(self.network(), self.broadcast())
    }

    /// Returns an `Iterator` over the subnets of this network with the
    /// given prefix length.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::{Ipv6Net, PrefixLenError};
    /// #
    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
    /// assert_eq!(net.subnets(18).unwrap().collect::<Vec<Ipv6Net>>(), vec![
    ///     "fd00::/18".parse::<Ipv6Net>().unwrap(),
    ///     "fd00:4000::/18".parse().unwrap(),
    ///     "fd00:8000::/18".parse().unwrap(),
    ///     "fd00:c000::/18".parse().unwrap(),
    /// ]);
    ///
    /// let net: Ipv6Net = "fd00::/126".parse().unwrap();
    /// assert_eq!(net.subnets(128).unwrap().collect::<Vec<Ipv6Net>>(), vec![
    ///     "fd00::/128".parse::<Ipv6Net>().unwrap(),
    ///     "fd00::1/128".parse().unwrap(),
    ///     "fd00::2/128".parse().unwrap(),
    ///     "fd00::3/128".parse().unwrap(),
    /// ]);
    ///
    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
    /// assert_eq!(net.subnets(15), Err(PrefixLenError));
    ///
    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
    /// assert_eq!(net.subnets(129), Err(PrefixLenError));
    /// ```
    pub fn subnets(&self, new_prefix_len: u8) -> Result<Ipv6Subnets, PrefixLenError> {
        if self.prefix_len > new_prefix_len || new_prefix_len > 128 {
            return Err(PrefixLenError);
        }
        
        Ok(Ipv6Subnets::new(
            self.network(),
            self.broadcast(),
            new_prefix_len,
        ))
    }

    /// Test if a network address contains either another network
    /// address or an IP address.
    ///
    /// # Examples
    ///
    /// ```
    /// # use std::net::Ipv6Addr;
    /// # use ipnet::Ipv6Net;
    /// #
    /// let net: Ipv6Net = "fd00::/16".parse().unwrap();
    /// let net_yes: Ipv6Net = "fd00::/17".parse().unwrap();
    /// let net_no: Ipv6Net = "fd00::/15".parse().unwrap();
    /// let ip_yes: Ipv6Addr = "fd00::1".parse().unwrap();
    /// let ip_no: Ipv6Addr = "fd01::".parse().unwrap();
    ///
    /// assert!(net.contains(&net));
    /// assert!(net.contains(&net_yes));
    /// assert!(!net.contains(&net_no));
    /// assert!(net.contains(&ip_yes));
    /// assert!(!net.contains(&ip_no));
    /// ```
    pub fn contains<T>(&self, other: T) -> bool where Self: Contains<T> {
        Contains::contains(self, other)
    }

    // It is significantly faster to work on u128 that Ipv6Addr.
    fn interval(&self) -> (u128, u128) {
        (
            u128::from(self.network()),
            u128::from(self.broadcast()).saturating_add(1),
        )
    }

    /// Aggregate a `Vec` of `Ipv6Net`s and return the result as a new
    /// `Vec`.
    ///
    /// # Examples
    ///
    /// ```
    /// # use ipnet::Ipv6Net;
    /// #
    /// let nets = vec![
    ///     "fd00::/18".parse::<Ipv6Net>().unwrap(),
    ///     "fd00:4000::/18".parse().unwrap(),
    ///     "fd00:8000::/18".parse().unwrap(),
    /// ];
    /// assert_eq!(Ipv6Net::aggregate(&nets), vec![
    ///     "fd00::/17".parse::<Ipv6Net>().unwrap(),
    ///     "fd00:8000::/18".parse().unwrap(),
    /// ]);
    /// ```
    pub fn aggregate(networks: &Vec<Ipv6Net>) -> Vec<Ipv6Net> {
        let mut intervals: Vec<(_, _)> = networks.iter().map(|n| n.interval()).collect();
        intervals = merge_intervals(intervals);
        let mut res: Vec<Ipv6Net> = Vec::new();

        for (start, mut end) in intervals {
            if end != std::u128::MAX {
                end = end.saturating_sub(1)
            }
            let iter = Ipv6Subnets::new(start.into(), end.into(), 0);
            res.extend(iter);
        }
        res
    }
}

impl Default for Ipv6Net {
    fn default() -> Self {
        Self {
            addr: Ipv6Addr::from(0),
            prefix_len: 0,
        }
    }
}

impl fmt::Debug for Ipv6Net {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt::Display::fmt(self, fmt)
    }
}

impl fmt::Display for Ipv6Net {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        write!(fmt, "{}/{}", self.addr, self.prefix_len)
    }
}

impl From<Ipv6Addr> for Ipv6Net {
    fn from(addr: Ipv6Addr) -> Ipv6Net {
        Ipv6Net { addr, prefix_len: 128 }
    }
}

/// Provides a method to test if a network address contains either
/// another network address or an IP address.
///
/// # Examples
///
/// ```
/// # use std::net::IpAddr;
/// # use ipnet::IpNet;
/// #
/// let n4_1: IpNet = "10.1.1.0/24".parse().unwrap();
/// let n4_2: IpNet = "10.1.1.0/26".parse().unwrap();
/// let n4_3: IpNet = "10.1.2.0/26".parse().unwrap();
/// let ip4_1: IpAddr = "10.1.1.1".parse().unwrap();
/// let ip4_2: IpAddr = "10.1.2.1".parse().unwrap();
///
/// let n6_1: IpNet = "fd00::/16".parse().unwrap();
/// let n6_2: IpNet = "fd00::/17".parse().unwrap();
/// let n6_3: IpNet = "fd01::/17".parse().unwrap();
/// let ip6_1: IpAddr = "fd00::1".parse().unwrap();
/// let ip6_2: IpAddr = "fd01::1".parse().unwrap();
///
/// assert!(n4_1.contains(&n4_2));
/// assert!(!n4_1.contains(&n4_3));
/// assert!(n4_1.contains(&ip4_1));
/// assert!(!n4_1.contains(&ip4_2));
///
/// assert!(n6_1.contains(&n6_2));
/// assert!(!n6_1.contains(&n6_3));
/// assert!(n6_1.contains(&ip6_1));
/// assert!(!n6_1.contains(&ip6_2));
///
/// assert!(!n4_1.contains(&n6_1) && !n6_1.contains(&n4_1));
/// assert!(!n4_1.contains(&ip6_1) && !n6_1.contains(&ip4_1));
/// ```
pub trait Contains<T> {
    fn contains(&self, other: T) -> bool;
}

impl<'a> Contains<&'a IpNet> for IpNet {
    fn contains(&self, other: &IpNet) -> bool {
        match (*self, *other) {
            (IpNet::V4(ref a), IpNet::V4(ref b)) => a.contains(b),
            (IpNet::V6(ref a), IpNet::V6(ref b)) => a.contains(b),
            _ => false,
        }
    }
}

impl<'a> Contains<&'a IpAddr> for IpNet {
    fn contains(&self, other: &IpAddr) -> bool {
        match (*self, *other) {
            (IpNet::V4(ref a), IpAddr::V4(ref b)) => a.contains(b),
            (IpNet::V6(ref a), IpAddr::V6(ref b)) => a.contains(b),
            _ => false,
        }
    }
}

impl<'a> Contains<&'a Ipv4Net> for Ipv4Net {
    fn contains(&self, other: &'a Ipv4Net) -> bool {
        self.network() <= other.network() && other.broadcast() <= self.broadcast()
    }
}

impl<'a> Contains<&'a Ipv4Addr> for Ipv4Net {
    fn contains(&self, other: &'a Ipv4Addr) -> bool {
        self.network() <= *other && *other <= self.broadcast()
    }
}

impl<'a> Contains<&'a Ipv6Net> for Ipv6Net {
    fn contains(&self, other: &'a Ipv6Net) -> bool {
        self.network() <= other.network() && other.broadcast() <= self.broadcast()
    }
}

impl<'a> Contains<&'a Ipv6Addr> for Ipv6Net {
    fn contains(&self, other: &'a Ipv6Addr) -> bool {
        self.network() <= *other && *other <= self.broadcast()
    }
}

/// An `Iterator` that generates IP network addresses, either IPv4 or
/// IPv6.
///
/// Generates the subnets between the provided `start` and `end` IP
/// addresses inclusive of `end`. Each iteration generates the next
/// network address of the largest valid size it can, while using a
/// prefix length not less than `min_prefix_len`.
///
/// # Examples
///
/// ```
/// # use std::net::{Ipv4Addr, Ipv6Addr};
/// # use std::str::FromStr;
/// # use ipnet::{IpNet, IpSubnets, Ipv4Subnets, Ipv6Subnets};
/// let subnets = IpSubnets::from(Ipv4Subnets::new(
///     "10.0.0.0".parse().unwrap(),
///     "10.0.0.239".parse().unwrap(),
///     26,
/// ));
/// 
/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
///     "10.0.0.0/26".parse().unwrap(),
///     "10.0.0.64/26".parse().unwrap(),
///     "10.0.0.128/26".parse().unwrap(),
///     "10.0.0.192/27".parse().unwrap(),
///     "10.0.0.224/28".parse().unwrap(),
/// ]);
///
/// let subnets = IpSubnets::from(Ipv6Subnets::new(
///     "fd00::".parse().unwrap(),
///     "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
///     26,
/// ));
/// 
/// assert_eq!(subnets.collect::<Vec<IpNet>>(), vec![
///     "fd00::/26".parse().unwrap(),
///     "fd00:40::/26".parse().unwrap(),
///     "fd00:80::/26".parse().unwrap(),
///     "fd00:c0::/27".parse().unwrap(),
///     "fd00:e0::/28".parse().unwrap(),
/// ]);
/// ```
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub enum IpSubnets {
    V4(Ipv4Subnets),
    V6(Ipv6Subnets),
}

/// An `Iterator` that generates IPv4 network addresses.
///
/// Generates the subnets between the provided `start` and `end` IP
/// addresses inclusive of `end`. Each iteration generates the next
/// network address of the largest valid size it can, while using a
/// prefix length not less than `min_prefix_len`.
///
/// # Examples
///
/// ```
/// # use std::net::Ipv4Addr;
/// # use std::str::FromStr;
/// # use ipnet::{Ipv4Net, Ipv4Subnets};
/// let subnets = Ipv4Subnets::new(
///     "10.0.0.0".parse().unwrap(),
///     "10.0.0.239".parse().unwrap(),
///     26,
/// );
/// 
/// assert_eq!(subnets.collect::<Vec<Ipv4Net>>(), vec![
///     "10.0.0.0/26".parse().unwrap(),
///     "10.0.0.64/26".parse().unwrap(),
///     "10.0.0.128/26".parse().unwrap(),
///     "10.0.0.192/27".parse().unwrap(),
///     "10.0.0.224/28".parse().unwrap(),
/// ]);
/// ```
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct Ipv4Subnets {
    start: Ipv4Addr,
    end: Ipv4Addr, // end is inclusive
    min_prefix_len: u8,
}

/// An `Iterator` that generates IPv6 network addresses.
///
/// Generates the subnets between the provided `start` and `end` IP
/// addresses inclusive of `end`. Each iteration generates the next
/// network address of the largest valid size it can, while using a
/// prefix length not less than `min_prefix_len`.
///
/// # Examples
///
/// ```
/// # use std::net::Ipv6Addr;
/// # use std::str::FromStr;
/// # use ipnet::{Ipv6Net, Ipv6Subnets};
/// let subnets = Ipv6Subnets::new(
///     "fd00::".parse().unwrap(),
///     "fd00:ef:ffff:ffff:ffff:ffff:ffff:ffff".parse().unwrap(),
///     26,
/// );
/// 
/// assert_eq!(subnets.collect::<Vec<Ipv6Net>>(), vec![
///     "fd00::/26".parse().unwrap(),
///     "fd00:40::/26".parse().unwrap(),
///     "fd00:80::/26".parse().unwrap(),
///     "fd00:c0::/27".parse().unwrap(),
///     "fd00:e0::/28".parse().unwrap(),
/// ]);
/// ```
#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug)]
pub struct Ipv6Subnets {
    start: Ipv6Addr,
    end: Ipv6Addr, // end is inclusive
    min_prefix_len: u8,
}

impl Ipv4Subnets {
    pub fn new(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Self {
        Ipv4Subnets {
            start: start,
            end: end,
            min_prefix_len: min_prefix_len,
        }
    }
}

impl Ipv6Subnets {
    pub fn new(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Self {
        Ipv6Subnets {
            start: start,
            end: end,
            min_prefix_len: min_prefix_len,
        }
    }
}

impl From<Ipv4Subnets> for IpSubnets {
    fn from(i: Ipv4Subnets) -> IpSubnets {
        IpSubnets::V4(i)
    }
}

impl From<Ipv6Subnets> for IpSubnets {
    fn from(i: Ipv6Subnets) -> IpSubnets {
        IpSubnets::V6(i)
    }
}

impl Iterator for IpSubnets {
    type Item = IpNet;

    fn next(&mut self) -> Option<Self::Item> {
        match *self {
            IpSubnets::V4(ref mut a) => a.next().map(IpNet::V4),
            IpSubnets::V6(ref mut a) => a.next().map(IpNet::V6),
        }
    }
}

fn next_ipv4_subnet(start: Ipv4Addr, end: Ipv4Addr, min_prefix_len: u8) -> Ipv4Net {
    let range = end.saturating_sub(start).saturating_add(1);
    if range == std::u32::MAX && min_prefix_len == 0 {
        Ipv4Net::new(start, min_prefix_len).unwrap()
    }
    else {
        let range_bits = 32u32.saturating_sub(range.leading_zeros()).saturating_sub(1);
        let start_tz = u32::from(start).trailing_zeros();
        let new_prefix_len = 32 - min(range_bits, start_tz);
        let next_prefix_len = max(new_prefix_len as u8, min_prefix_len);
        Ipv4Net::new(start, next_prefix_len).unwrap()
    }
}

fn next_ipv6_subnet(start: Ipv6Addr, end: Ipv6Addr, min_prefix_len: u8) -> Ipv6Net {
    let range = end.saturating_sub(start).saturating_add(1);
    if range == std::u128::MAX && min_prefix_len == 0 {
        Ipv6Net::new(start, min_prefix_len).unwrap()
    }
    else {
        let range = end.saturating_sub(start).saturating_add(1);
        let range_bits = 128u32.saturating_sub(range.leading_zeros()).saturating_sub(1);
        let start_tz = u128::from(start).trailing_zeros();
        let new_prefix_len = 128 - min(range_bits, start_tz);
        let next_prefix_len = max(new_prefix_len as u8, min_prefix_len);
        Ipv6Net::new(start, next_prefix_len).unwrap()
    }
}

impl Iterator for Ipv4Subnets {
    type Item = Ipv4Net;

    fn next(&mut self) -> Option<Self::Item> {
        match self.start.partial_cmp(&self.end) {
            Some(Less) => {
                let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
                self.start = next.broadcast().saturating_add(1);

                // Stop the iterator if we saturated self.start. This
                // check worsens performance slightly but overall this
                // approach of operating on Ipv4Addr types is faster
                // than what we were doing before using Ipv4Net.
                if self.start == next.broadcast() {
                    self.end.replace_zero();
                }
                Some(next)
            },
            Some(Equal) => {
                let next = next_ipv4_subnet(self.start, self.end, self.min_prefix_len);
                self.start = next.broadcast().saturating_add(1);
                self.end.replace_zero();
                Some(next)
            },
            _ => None,
        }
    }
}

impl Iterator for Ipv6Subnets {
    type Item = Ipv6Net;

    fn next(&mut self) -> Option<Self::Item> {
        match self.start.partial_cmp(&self.end) {
            Some(Less) => {
                let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
                self.start = next.broadcast().saturating_add(1);

                // Stop the iterator if we saturated self.start. This
                // check worsens performance slightly but overall this
                // approach of operating on Ipv6Addr types is faster
                // than what we were doing before using Ipv6Net.
                if self.start == next.broadcast() {
                    self.end.replace_zero();
                }
                Some(next)
            },
            Some(Equal) => {
                let next = next_ipv6_subnet(self.start, self.end, self.min_prefix_len);
                self.start = next.broadcast().saturating_add(1);
                self.end.replace_zero();
                Some(next)
            },
            _ => None,
        }
    }
}

impl FusedIterator for IpSubnets {}
impl FusedIterator for Ipv4Subnets {}
impl FusedIterator for Ipv6Subnets {}

// Generic function for merging a vector of intervals.
fn merge_intervals<T: Copy + Ord>(mut intervals: Vec<(T, T)>) -> Vec<(T, T)> {
    if intervals.len() == 0 {
        return intervals;
    }

    intervals.sort();
    let mut res: Vec<(T, T)> = Vec::new();
    let (mut start, mut end) = intervals[0];
    
    let mut i = 1;
    let len = intervals.len();
    while i < len {
        let (next_start, next_end) = intervals[i];
        if end >= next_start {
            start = min(start, next_start);
            end = max(end, next_end);
        }
        else {
            res.push((start, end));
            start = next_start;
            end = next_end;
        }
        i += 1;
    }

    res.push((start, end));
    res
}

#[cfg(test)]
mod tests {
    use super::*;

    macro_rules! make_ipnet_vec {
        ($($x:expr),*) => ( vec![$($x.parse::<IpNet>().unwrap(),)*] );
        ($($x:expr,)*) => ( make_ipnet_vec![$($x),*] );
    }

    #[test]
    fn test_make_ipnet_vec() {
        assert_eq!(
            make_ipnet_vec![
                "10.1.1.1/32", "10.2.2.2/24", "10.3.3.3/16",
                "fd00::1/128", "fd00::2/127", "fd00::3/126",
            ],
            vec![
                "10.1.1.1/32".parse().unwrap(),
                "10.2.2.2/24".parse().unwrap(),
                "10.3.3.3/16".parse().unwrap(),
                "fd00::1/128".parse().unwrap(),
                "fd00::2/127".parse().unwrap(),
                "fd00::3/126".parse().unwrap(),
            ]
        );
    }

    #[test]
    fn test_merge_intervals() {
        let v = vec![
            (0, 1), (1, 2), (2, 3),
            (11, 12), (13, 14), (10, 15), (11, 13),
            (20, 25), (24, 29),
        ];

        let v_ok = vec![
            (0, 3),
            (10, 15),
            (20, 29),
        ];

        let vv = vec![
            ([0, 1], [0, 2]), ([0, 2], [0, 3]), ([0, 0], [0, 1]),
            ([10, 15], [11, 0]), ([10, 0], [10, 16]),
        ];

        let vv_ok = vec![
            ([0, 0], [0, 3]),
            ([10, 0], [11, 0]),
        ];

        assert_eq!(merge_intervals(v), v_ok);
        assert_eq!(merge_intervals(vv), vv_ok);
    }

    macro_rules! make_ipv4_subnets_test {
        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
            #[test]
            fn $name() {
                let subnets = IpSubnets::from(Ipv4Subnets::new(
                    $start.parse().unwrap(),
                    $end.parse().unwrap(),
                    $min_prefix_len,
                ));
                let results = make_ipnet_vec![$($x),*];
                assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
            }
        );
        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
            make_ipv4_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
        );
    }

    macro_rules! make_ipv6_subnets_test {
        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr),*) => (
            #[test]
            fn $name() {
                let subnets = IpSubnets::from(Ipv6Subnets::new(
                    $start.parse().unwrap(),
                    $end.parse().unwrap(),
                    $min_prefix_len,
                ));
                let results = make_ipnet_vec![$($x),*];
                assert_eq!(subnets.collect::<Vec<IpNet>>(), results);
            }
        );
        ($name:ident, $start:expr, $end:expr, $min_prefix_len:expr, $($x:expr,)*) => (
            make_ipv6_subnets_test!($name, $start, $end, $min_prefix_len, $($x),*);
        );
    }

    make_ipv4_subnets_test!(
        test_ipv4_subnets_zero_zero,
        "0.0.0.0", "0.0.0.0", 0,
        "0.0.0.0/32",
    );

    make_ipv4_subnets_test!(
        test_ipv4_subnets_zero_max,
        "0.0.0.0", "255.255.255.255", 0,
        "0.0.0.0/0",
    );

    make_ipv4_subnets_test!(
        test_ipv4_subnets_max_max,
        "255.255.255.255", "255.255.255.255", 0,
        "255.255.255.255/32",
    );
    
    make_ipv4_subnets_test!(
        test_ipv4_subnets_none,
        "0.0.0.1", "0.0.0.0", 0,
    );
    
    make_ipv4_subnets_test!(
        test_ipv4_subnets_one,
        "0.0.0.0", "0.0.0.1", 0,
        "0.0.0.0/31",
    );

    make_ipv4_subnets_test!(
        test_ipv4_subnets_two,
        "0.0.0.0", "0.0.0.2", 0,
        "0.0.0.0/31",
        "0.0.0.2/32",
    );
    
    make_ipv4_subnets_test!(
        test_ipv4_subnets_taper,
        "0.0.0.0", "0.0.0.10", 30,
        "0.0.0.0/30",
        "0.0.0.4/30",
        "0.0.0.8/31",
        "0.0.0.10/32",
    );
    
    make_ipv6_subnets_test!(
        test_ipv6_subnets_zero_zero,
        "::", "::", 0,
        "::/128",
    );

    make_ipv6_subnets_test!(
        test_ipv6_subnets_zero_max,
        "::", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
        "::/0",
    );

    make_ipv6_subnets_test!(
        test_ipv6_subnets_max_max,
        "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 0,
        "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128",
    );
    
    make_ipv6_subnets_test!(
        test_ipv6_subnets_none,
        "::1", "::", 0,
    );
    
    make_ipv6_subnets_test!(
        test_ipv6_subnets_one,
        "::", "::1", 0,
        "::/127",
    );

    make_ipv6_subnets_test!(
        test_ipv6_subnets_two,
        "::", "::2", 0,
        "::/127",
        "::2/128",
    );

    make_ipv6_subnets_test!(
        test_ipv6_subnets_taper,
        "::", "::a", 126,
        "::/126",
        "::4/126",
        "::8/127",
        "::a/128",
    );

    #[test]
    fn test_aggregate() {
        let ip_nets = make_ipnet_vec![
            "10.0.0.0/24", "10.0.1.0/24", "10.0.1.1/24", "10.0.1.2/24",
            "10.0.2.0/24",
            "10.1.0.0/24", "10.1.1.0/24",
            "192.168.0.0/24", "192.168.1.0/24", "192.168.2.0/24", "192.168.3.0/24",
            "fd00::/32", "fd00:1::/32",
            "fd00:2::/32",
        ];

        let ip_aggs = make_ipnet_vec![
            "10.0.0.0/23",
            "10.0.2.0/24",
            "10.1.0.0/23",
            "192.168.0.0/22",
            "fd00::/31",
            "fd00:2::/32",
        ];

        let ipv4_nets: Vec<Ipv4Net> = ip_nets.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect();
        let ipv4_aggs: Vec<Ipv4Net> = ip_aggs.iter().filter_map(|p| if let IpNet::V4(x) = *p { Some(x) } else { None }).collect();
        let ipv6_nets: Vec<Ipv6Net> = ip_nets.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect();
        let ipv6_aggs: Vec<Ipv6Net> = ip_aggs.iter().filter_map(|p| if let IpNet::V6(x) = *p { Some(x) } else { None }).collect();

        assert_eq!(IpNet::aggregate(&ip_nets), ip_aggs);
        assert_eq!(Ipv4Net::aggregate(&ipv4_nets), ipv4_aggs);
        assert_eq!(Ipv6Net::aggregate(&ipv6_nets), ipv6_aggs);
    }
    
    #[test]
    fn test_aggregate_issue44() {
        let nets: Vec<Ipv4Net> = vec!["128.0.0.0/1".parse().unwrap()];
        assert_eq!(Ipv4Net::aggregate(&nets), nets);

        let nets: Vec<Ipv4Net> = vec!["0.0.0.0/1".parse().unwrap(), "128.0.0.0/1".parse().unwrap()];
        assert_eq!(Ipv4Net::aggregate(&nets), vec!["0.0.0.0/0".parse().unwrap()]);

        let nets: Vec<Ipv6Net> = vec!["8000::/1".parse().unwrap()];
        assert_eq!(Ipv6Net::aggregate(&nets), nets);

        let nets: Vec<Ipv6Net> = vec!["::/1".parse().unwrap(), "8000::/1".parse().unwrap()];
        assert_eq!(Ipv6Net::aggregate(&nets), vec!["::/0".parse().unwrap()]);
    }

    #[test]
    fn ipnet_default() {
        let ipnet: IpNet = "0.0.0.0/0".parse().unwrap();
        assert_eq!(ipnet, IpNet::default());
    }

    #[test]
    fn ipv4net_default() {
        let ipnet: Ipv4Net = "0.0.0.0/0".parse().unwrap();
        assert_eq!(ipnet, Ipv4Net::default());
    }

    #[test]
    fn ipv6net_default() {
        let ipnet: Ipv6Net = "::/0".parse().unwrap();
        assert_eq!(ipnet, Ipv6Net::default());
    }
}
