// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use crate::configuration::{ClientConfig, ServerConfig};
use crate::protocol::{self, ConfigOption, Message, MessageType, OpCode, OptionCode};
use failure::Fail;
use byteorder::{BigEndian, ByteOrder};
use fidl_fuchsia_hardware_ethernet_ext::MacAddress as MacAddr;
use std::cmp;
use std::collections::{BTreeSet, HashMap, HashSet};
use std::net::Ipv4Addr;
use std::ops::Fn;


/// A minimal DHCP server.
///
/// This comment will be expanded upon in future CLs as the server design
/// is iterated upon.
pub struct Server<F>
where
    F: Fn() -> i64,
{
    cache: CachedClients,
    pool: AddressPool,
    config: ServerConfig,
    time_provider: F,
}

// A wrapper around the error types which can be returned
// by DHCP Server in response to client requests
#[derive(Debug, Fail, PartialEq)]
pub enum ServerError {
    #[fail(display = "Received Client Message Type is invalid : {:?}", _0)]
    InvalidClientMessage(MessageType),

    #[fail(display = "Requested Ipv4 Address by client is invalid : {}", _0)]
    BadRequestedIpv4Addr(String),

    #[fail(display = "Server encountered error in local address pool manipulation : {}", _0)]
    ServerAddressPoolFailure(AddressPoolError),

    #[fail(display = "Server is not the intended target for this client request.")]
    UnwantedDHCPServer,

    #[fail(display = "Unable to assign the requested ipv4 address to client : {}", _0)]
    RequestedAddrAssignmentFailure(String),

    #[fail(display = "Requested Ipv4Addr not found")]
    RequestedIpv4AddrNotFound,

    #[fail(display = "Client Mac address could not be identified")]
    UnknownClientMac,

    #[fail(display = "Client State could not be identified during Init Reboot")]
    UnknownClientStatAtReboot,

    #[fail(display = "The declined Ipv4 address by client not found in server pool")]
    DeclinedIpv4AddrNotFound,

    #[fail(display = "Client declined offered Ipv4 address : {}", _0)]
    ClientDeclinedOfferedAddr(Ipv4Addr),

    #[fail(display = "Client released Ipv4 address : {}", _0)]
    ClientReleasedIpv4Addr(Ipv4Addr),

    #[fail(display = "Unable to identify Client Request Type")]
    UnknownClientRequest
}

impl From<AddressPoolError> for ServerError {
    fn from(e: AddressPoolError) -> Self {
        ServerError::ServerAddressPoolFailure(e)
    }
}

impl<F> Server<F>
where
    F: Fn() -> i64,
{
    /// Returns an initialized `Server` value.
    pub fn new(time_provider: F) -> Server<F> {
        Server {
            cache: HashMap::new(),
            pool: AddressPool::new(),
            config: ServerConfig::new(),
            time_provider: time_provider,
        }
    }

    /// Instantiates a `Server` value from the provided `ServerConfig`.
    pub fn from_config(config: ServerConfig, time_provider: F) -> Server<F> {
        let mut server = Server {
            cache: HashMap::new(),
            pool: AddressPool::new(),
            config: config,
            time_provider: time_provider,
        };
        server.pool.load_pool(&server.config.managed_addrs);
        server
    }

    /// Dispatches an incoming DHCP message to the appropriate handler for processing.
    ///
    /// If the incoming message is a valid client DHCP message, then the server will attempt to
    /// take appropriate action to serve the client's request, update the internal server state,
    /// and return a response Ok(Message) in the 'Result'. If the incoming message is invalid,
    /// or the server is unable to serve the request, or the processing of the client's request
    /// resulted in an error, then `dispatch()` will return `Err(ServerError)` as the 'Result'.
    /// with the necessary information about the error
    pub fn dispatch(&mut self, msg: Message) -> Result<Message, ServerError> {
        match msg.get_dhcp_type() {
            Some(MessageType::DHCPDISCOVER) => self.handle_discover(msg),
            Some(MessageType::DHCPOFFER) => Err(ServerError::InvalidClientMessage(MessageType::DHCPOFFER)),
            Some(MessageType::DHCPREQUEST) => self.handle_request(msg),
            Some(MessageType::DHCPDECLINE) => self.handle_decline(msg),
            Some(MessageType::DHCPACK) => Err(ServerError::InvalidClientMessage(MessageType::DHCPACK)),
            Some(MessageType::DHCPNAK) => Err(ServerError::InvalidClientMessage(MessageType::DHCPNAK)),
            Some(MessageType::DHCPRELEASE) => self.handle_release(msg),
            Some(MessageType::DHCPINFORM) => self.handle_inform(msg),
            None => Err(ServerError::UnknownClientRequest),
        }
    }

    fn handle_discover(&mut self, disc: Message) -> Result<Message, ServerError> {
        let client_config = self.client_config(&disc);
        let offered_ip = self.get_addr(&disc)?;
        let mut offer = build_offer(disc, &self.config, &client_config);
        offer.yiaddr = offered_ip;
        let () = self.update_server_cache(
            Ipv4Addr::from(offer.yiaddr),
            offer.chaddr,
            vec![],
            &client_config,
        )?;

        Ok(offer)
    }

    fn get_addr(&mut self, client: &Message) -> Result<Ipv4Addr, ServerError> {
        if let Some(config) = self.cache.get(&client.chaddr) {
            if !config.expired((self.time_provider)()) {
                // Free cached address so that it can be reallocated to same client.
                let () = self.pool.free_addr(config.client_addr)?;
                return Ok(config.client_addr);
            } else if self.pool.addr_is_available(config.client_addr) {
                return Ok(config.client_addr);
            }
        }
        if let Some(opt) = client.get_config_option(OptionCode::RequestedIpAddr) {
            if opt.value.len() >= 4 {
                let requested_addr = protocol::ip_addr_from_buf_at(&opt.value, 0)
                    .ok_or_else(|| ServerError::BadRequestedIpv4Addr("out of range indexing on opt.value".to_owned()))?;
                if self.pool.addr_is_available(requested_addr) {
                    return Ok(requested_addr);
                }
            }
        }
        let addr = self.pool.get_next_available_addr()?;
        Ok(addr)
    }

    fn update_server_cache(
        &mut self,
        client_addr: Ipv4Addr,
        client_mac: MacAddr,
        client_opts: Vec<ConfigOption>,
        client_config: &ClientConfig,
    ) -> Result<(), ServerError> {
        let config = CachedConfig {
            client_addr: client_addr,
            options: client_opts,
            expiration: (self.time_provider)() + client_config.lease_time_s as i64,
        };
        self.cache.insert(client_mac, config);
        let () = self.pool.allocate_addr(client_addr)?;
        Ok(())
    }

    fn handle_request(&mut self, req: Message) -> Result<Message, ServerError> {
        match get_client_state(&req) {
            ClientState::Selecting => self.handle_request_selecting(req),
            ClientState::InitReboot => self.handle_request_init_reboot(req),
            ClientState::Renewing => self.handle_request_renewing(req),
            ClientState::Unknown => Err(ServerError::UnknownClientStatAtReboot),
        }
    }

    fn handle_request_selecting(&mut self, req: Message) -> Result<Message, ServerError> {
        let requested_ip = req.ciaddr;
        if !is_recipient(self.config.server_ip, &req) {
            Err(ServerError::UnwantedDHCPServer)
        } else {
            let () = self.check_ip_allocation(&req, requested_ip)?;
            Ok(build_ack(req, requested_ip, &self.config))
        }
        /*
          let requested_ip = req.ciaddr;
        if !is_recipient(self.config.server_ip, &req) || !self.is_assigned(&req, requested_ip) {
            return Err(ServerError::IncorrectDHCP);
        }
        Some(build_ack(req, requested_ip, &self.config))

        */
    }

    fn check_ip_allocation(&self, req: &Message, requested_ip: Ipv4Addr) -> Result<(), ServerError> {
        if let Some(client_config) = self.cache.get(&req.chaddr) {
            if client_config.client_addr != requested_ip {
                Err(ServerError::RequestedAddrAssignmentFailure("Requested Ipv4 \
                address does not match initial address requested in discovery".to_owned()))
            } else if client_config.expired((self.time_provider)()) {
                Err(ServerError::RequestedAddrAssignmentFailure("Client Config has expired".to_owned()))
            } else if !self.pool.addr_is_allocated(requested_ip) {
                Err(ServerError::RequestedAddrAssignmentFailure("Server failed to reserve requested Ipv4 adddress".to_owned()))
            } else {
                Ok(())
            }
        } else {
            Err(ServerError::RequestedAddrAssignmentFailure("Could not retrieve client config".to_owned()))
        }
/*        if let Some(client_config) = self.cache.get(&req.chaddr) {
            client_config.client_addr == requested_ip
                && !client_config.expired((self.time_provider)())
                && self.pool.addr_is_allocated(requested_ip)
        } else {
            false
        }*/
    }

    fn handle_request_init_reboot(&mut self, req: Message) -> Result<Message, ServerError> {
        let requested_ip = get_requested_ip_addr(&req).ok_or_else(|| ServerError::RequestedIpv4AddrNotFound)?;
        if !is_in_subnet(requested_ip, &self.config) {
            //return Ok(build_nak(req, &self.config))
            let msg = build_nak(req, &self.config);
/*            let s = String::from("hello world");
            add_request_nak_message(&mut msg, s);*/
            return Ok(msg)
        }
        if !is_client_mac_known(req.chaddr, &self.cache) {
            return Err(ServerError::UnknownClientMac)
        }
        if self.check_ip_allocation(&req, requested_ip).is_err() {
            return Ok(build_nak(req, &self.config))
        }
        Ok(build_ack(req, requested_ip, &self.config))
    }

    fn handle_request_renewing(&mut self, req: Message) -> Result<Message, ServerError> {
        let client_ip = req.ciaddr;
        let () = self.check_ip_allocation(&req, client_ip)?;
/*        if !self.is_assigned(&req, client_ip) {
            return None;
        }*/
        Ok(build_ack(req, client_ip, &self.config))
    }

    fn handle_decline(&mut self, dec: Message) -> Result<Message, ServerError> {
        let declined_ip = get_requested_ip_addr(&dec).ok_or_else(|| ServerError::DeclinedIpv4AddrNotFound)?;
        if is_recipient(self.config.server_ip, &dec) && self.check_ip_allocation(&dec, declined_ip).is_err() {
            let () = self.pool.allocate_addr(declined_ip)?;
        }
        self.cache.remove(&dec.chaddr);
        Err(ServerError::ClientDeclinedOfferedAddr(declined_ip))
/*        let declined_ip = get_requested_ip_addr(&dec)?;
        if is_recipient(self.config.server_ip, &dec) && !self.is_assigned(&dec, declined_ip) {
            self.pool.allocate_addr(declined_ip);
        }
        self.cache.remove(&dec.chaddr);
        None*/
    }

    fn handle_release(&mut self, rel: Message) -> Result<Message, ServerError> {
        if self.cache.contains_key(&rel.chaddr) {
            let () = self.pool.free_addr(rel.ciaddr)?;
        }
        Err(ServerError::ClientReleasedIpv4Addr(rel.ciaddr))
    }

    fn handle_inform(&mut self, inf: Message) -> Result<Message, ServerError> {
        // When responding to an INFORM, the server must leave yiaddr zeroed.
        let yiaddr = Ipv4Addr::new(0, 0, 0, 0);
        let mut ack = build_ack(inf, yiaddr, &self.config);
        ack.options.clear();
        add_inform_ack_options(&mut ack, &self.config);
        Ok(ack)
    }

    /// Releases all allocated IP addresses whose leases have expired back to
    /// the pool of addresses available for allocation.
    pub fn release_expired_leases(&mut self) {
        let now = (self.time_provider)();
        let expired_clients: Vec<(MacAddr, Ipv4Addr)> = self
            .cache
            .iter()
            .filter(|(_mac, config)| config.expired(now))
            .map(|(mac, config)| (*mac, config.client_addr))
            .collect();
        // Expired client entries must be removed in a separate statement because otherwise we
        // would be attempting to change a cache as we iterate over it.
        expired_clients.iter().for_each(|(mac, ip)| {
            let _ = self.pool.free_addr(*ip);
            self.cache.remove(mac);
        });
    }

    pub fn client_config(&self, client_message: &Message) -> ClientConfig {
        let requested_config = client_message.parse_to_config();
        ClientConfig {
            lease_time_s: match requested_config.lease_time_s {
                None => self.config.default_lease_time,
                Some(t) => cmp::min(t, self.config.max_lease_time_s),
            },
        }
    }
}

/// A cache mapping clients to their configuration data.
///
/// The server should store configuration data for all clients
/// to which it has sent a DHCPOFFER message. Entries in the cache
/// will eventually timeout, although such functionality is currently
/// unimplemented.
type CachedClients = HashMap<MacAddr, CachedConfig>;

#[derive(Clone, Debug, PartialEq)]
struct CachedConfig {
    client_addr: Ipv4Addr,
    options: Vec<ConfigOption>,
    expiration: i64,
}

impl Default for CachedConfig {
    fn default() -> Self {
        CachedConfig {
            client_addr: Ipv4Addr::new(0, 0, 0, 0),
            options: vec![],
            expiration: std::i64::MAX,
        }
    }
}

impl CachedConfig {
    fn expired(&self, now: i64) -> bool {
        self.expiration <= now
    }
}

/// The pool of addresses managed by the server.
///
/// Any address managed by the server should be stored in only one
/// of the available/allocated sets at a time. In other words, an
/// address in `available_addrs` must not be in `allocated_addrs` and
/// vice-versa.
#[derive(Debug)]
struct AddressPool {
    // available_addrs uses a BTreeSet so that addresses are allocated
    // in a deterministic order.
    available_addrs: BTreeSet<Ipv4Addr>,
    allocated_addrs: HashSet<Ipv4Addr>,
}

//This is a wrapper around different errors that could be returned by
// the DHCP server address pool during address allocation/de-allocation
#[derive(Debug, Fail, PartialEq)]
pub enum AddressPoolError {

    #[fail(display = "Address Pool does not have any more available Ipv4 addresses")]
    Ipv4AddrExhaustion,

    #[fail(display = "Invalid Server State: attempted to allocate unavailable address : {}", _0)]
    UnavailableIpv4AddrAllocation(Ipv4Addr),

    #[fail(display = "Invalid Server State: attempted to free unallocated address : {}", _0)]
    UnallocatedIpv4AddrRelease(Ipv4Addr),
}

impl AddressPool {
    fn new() -> Self {
        AddressPool { available_addrs: BTreeSet::new(), allocated_addrs: HashSet::new() }
    }

    fn load_pool(&mut self, addrs: &[Ipv4Addr]) {
        for addr in addrs {
            if !self.allocated_addrs.contains(&addr) {
                self.available_addrs.insert(*addr);
            }
        }
    }

    //TODO(sshrivy): Should the address be chosen as per the client subnet
    //
    //RFC2131#section-4.3.1
    //
    //A new address allocated from the server's pool of available
    //addresses; the address is selected based on the subnet from which
    //the message was received (if 'giaddr' is 0) or on the address of
    //the relay agent that forwarded the message ('giaddr' when not 0)
    fn get_next_available_addr(&self) -> Result<Ipv4Addr, AddressPoolError> {
        let mut iter = self.available_addrs.iter();
        match iter.next() {
            Some(addr) => Ok(*addr),
            None => Err(AddressPoolError::Ipv4AddrExhaustion),
        }
    }

    fn allocate_addr(&mut self, addr: Ipv4Addr) -> Result<(), AddressPoolError>  {
        if self.available_addrs.remove(&addr) {
            self.allocated_addrs.insert(addr);
            Ok(())
        } else {
            Err(AddressPoolError::UnavailableIpv4AddrAllocation(addr))
        }
    }

    fn free_addr(&mut self, addr: Ipv4Addr) -> Result<(), AddressPoolError> {
        if self.allocated_addrs.remove(&addr) {
            self.available_addrs.insert(addr);
            Ok(())
        } else {
            Err(AddressPoolError::UnallocatedIpv4AddrRelease(addr))
        }
    }

    fn addr_is_available(&self, addr: Ipv4Addr) -> bool {
        self.available_addrs.contains(&addr) && !self.allocated_addrs.contains(&addr)
    }

    fn addr_is_allocated(&self, addr: Ipv4Addr) -> bool {
        !self.available_addrs.contains(&addr) && self.allocated_addrs.contains(&addr)
    }
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum ClientState {
    Unknown,
    Selecting,
    InitReboot,
    Renewing,
}

fn build_offer(client: Message, config: &ServerConfig, client_config: &ClientConfig) -> Message {
    let mut offer = client;
    offer.op = OpCode::BOOTREPLY;
    offer.secs = 0;
    offer.ciaddr = Ipv4Addr::new(0, 0, 0, 0);
    offer.siaddr = Ipv4Addr::new(0, 0, 0, 0);
    offer.sname = String::new();
    offer.file = String::new();
    add_required_options(&mut offer, config, client_config, MessageType::DHCPOFFER);
    add_recommended_options(&mut offer, config);

    offer
}

fn add_required_options(
    msg: &mut Message,
    config: &ServerConfig,
    client_config: &ClientConfig,
    msg_type: MessageType,
) {
    msg.options.clear();
    let mut lease = vec![0; 4];
    BigEndian::write_u32(&mut lease, client_config.lease_time_s);
    msg.options.push(ConfigOption { code: OptionCode::IpAddrLeaseTime, value: lease });
    msg.options.push(ConfigOption {
        code: OptionCode::SubnetMask,
        value: config.subnet_mask.octets().to_vec(),
    });
    msg.options
        .push(ConfigOption { code: OptionCode::DhcpMessageType, value: vec![msg_type.into()] });
    msg.options.push(ConfigOption {
        code: OptionCode::ServerId,
        value: config.server_ip.octets().to_vec(),
    });
}

fn add_recommended_options(msg: &mut Message, config: &ServerConfig) {
    msg.options
        .push(ConfigOption { code: OptionCode::Router, value: ip_vec_to_bytes(&config.routers) });
    msg.options.push(ConfigOption {
        code: OptionCode::NameServer,
        value: ip_vec_to_bytes(&config.name_servers),
    });
    let mut renewal_time = vec![0, 0, 0, 0];
    BigEndian::write_u32(&mut renewal_time, config.default_lease_time / 2);
    msg.options.push(ConfigOption { code: OptionCode::RenewalTime, value: renewal_time });
    let mut rebinding_time = vec![0, 0, 0, 0];
    BigEndian::write_u32(&mut rebinding_time, config.default_lease_time / 4);
    msg.options.push(ConfigOption { code: OptionCode::RebindingTime, value: rebinding_time });
}

fn add_inform_ack_options(msg: &mut Message, config: &ServerConfig) {
    msg.options.push(ConfigOption {
        code: OptionCode::DhcpMessageType,
        value: vec![MessageType::DHCPINFORM.into()],
    });
    msg.options.push(ConfigOption {
        code: OptionCode::ServerId,
        value: config.server_ip.octets().to_vec(),
    });
    msg.options
        .push(ConfigOption { code: OptionCode::Router, value: ip_vec_to_bytes(&config.routers) });
    msg.options.push(ConfigOption {
        code: OptionCode::NameServer,
        value: ip_vec_to_bytes(&config.name_servers),
    });
}

fn ip_vec_to_bytes<'a, T>(ips: T) -> Vec<u8>
where
    T: IntoIterator<Item = &'a Ipv4Addr>,
{
    ips.into_iter().flat_map(|ip| ip.octets().to_vec()).collect()
}

fn is_recipient(server_ip: Ipv4Addr, req: &Message) -> bool {
    if let Some(server_id) = get_server_id_from(&req) {
        return server_id == server_ip;
    }
    false
}

fn build_ack(req: Message, requested_ip: Ipv4Addr, config: &ServerConfig) -> Message {
    let mut ack = req;
    ack.op = OpCode::BOOTREPLY;
    ack.secs = 0;
    ack.yiaddr = requested_ip;
    ack.options.clear();
    add_required_options(
        &mut ack,
        config,
        &ClientConfig::new(config.default_lease_time),
        MessageType::DHCPACK,
    );
    add_recommended_options(&mut ack, config);

    ack
}

fn is_in_subnet(ip: Ipv4Addr, config: &ServerConfig) -> bool {
    config.subnet_mask.apply_to(ip) == config.subnet_mask.apply_to(config.server_ip)
}

fn is_client_mac_known(mac: MacAddr, cache: &CachedClients) -> bool {
    cache.get(&mac).is_some()
}

fn build_nak(req: Message, config: &ServerConfig) -> Message {
    let mut nak = req;
    nak.op = OpCode::BOOTREPLY;
    nak.secs = 0;
    nak.ciaddr = Ipv4Addr::new(0, 0, 0, 0);
    nak.yiaddr = Ipv4Addr::new(0, 0, 0, 0);
    nak.siaddr = Ipv4Addr::new(0, 0, 0, 0);
    nak.options.clear();
    let mut lease = vec![0; 4];
    BigEndian::write_u32(&mut lease, config.default_lease_time);
    nak.options.push(ConfigOption {
        code: OptionCode::DhcpMessageType,
        value: vec![MessageType::DHCPNAK.into()],
    });
    nak.options.push(ConfigOption {
        code: OptionCode::ServerId,
        value: config.server_ip.octets().to_vec(),
    });

    nak
}

/*fn add_request_nak_message(nak: &mut Message, msg: String) {
    nak.options.push(ConfigOption {
        code: OptionCode::Message,
        value: msg.into_bytes(),
    });
}*/

fn get_client_state(msg: &Message) -> ClientState {
    let maybe_server_id = get_server_id_from(&msg);
    let maybe_requested_ip = get_requested_ip_addr(&msg);
    let zero_ciaddr = Ipv4Addr::new(0, 0, 0, 0);

    if maybe_server_id.is_some() && maybe_requested_ip.is_none() && msg.ciaddr != zero_ciaddr {
        return ClientState::Selecting;
    } else if maybe_requested_ip.is_some() && msg.ciaddr == zero_ciaddr {
        return ClientState::InitReboot;
    } else if msg.ciaddr != zero_ciaddr {
        return ClientState::Renewing;
    } else {
        return ClientState::Unknown;
    }
}

fn get_requested_ip_addr(req: &Message) -> Option<Ipv4Addr> {
    let req_ip_opt = req.options.iter().find(|opt| opt.code == OptionCode::RequestedIpAddr)?;
    let raw_ip = BigEndian::read_u32(&req_ip_opt.value);
    Some(Ipv4Addr::from(raw_ip))
}

fn get_server_id_from(req: &Message) -> Option<Ipv4Addr> {
    let server_id_opt = req.options.iter().find(|opt| opt.code == OptionCode::ServerId)?;
    let raw_server_id = BigEndian::read_u32(&server_id_opt.value);
    Some(Ipv4Addr::from(raw_server_id))
}

#[cfg(test)]
mod tests {

    use super::*;
    use crate::configuration::SubnetMask;
    use crate::protocol::{ConfigOption, Message, MessageType, OpCode, OptionCode};
    use std::convert::TryFrom;
    use std::net::Ipv4Addr;
    //use std::str::from_utf8;

    fn new_test_server<F>(time_provider: F) -> Server<F>
    where
        F: Fn() -> i64,
    {
        let mut server = Server::new(time_provider);
        server.config.server_ip = Ipv4Addr::new(192, 168, 1, 1);
        server.config.default_lease_time = 100;
        server.config.routers.push(Ipv4Addr::new(192, 168, 1, 1));
        server
            .config
            .name_servers
            .extend_from_slice(&vec![Ipv4Addr::new(8, 8, 8, 8), Ipv4Addr::new(8, 8, 4, 4)]);
        server.pool.available_addrs.insert(Ipv4Addr::from([192, 168, 1, 2]));
        server
    }

    fn new_test_discover() -> Message {
        let mut disc = Message::new();
        disc.xid = 42;
        disc.chaddr = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
        disc.options.push(ConfigOption {
            code: OptionCode::DhcpMessageType,
            value: vec![MessageType::DHCPDISCOVER.into()],
        });
        disc
    }

    fn new_test_client_offer() -> Message {
        let mut client_offer = Message::new();
        client_offer.op = OpCode::BOOTREQUEST;
        client_offer.xid = 42;
        client_offer.chaddr = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
        client_offer.options.push(ConfigOption {
            code: OptionCode::DhcpMessageType,
            value: vec![MessageType::DHCPOFFER.into()],
        });
        // Skipping other settings as they are not needed
        client_offer
    }

    fn new_test_offer() -> Message {
        let mut offer = Message::new();
        offer.op = OpCode::BOOTREPLY;
        offer.xid = 42;
        offer.yiaddr = Ipv4Addr::new(192, 168, 1, 2);
        offer.chaddr = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
        offer
            .options
            .push(ConfigOption { code: OptionCode::IpAddrLeaseTime, value: vec![0, 0, 0, 100] });
        offer.options.push(ConfigOption {
            code: OptionCode::SubnetMask,
            value: SubnetMask::try_from(24).unwrap().octets().to_vec(),
        });
        offer.options.push(ConfigOption {
            code: OptionCode::DhcpMessageType,
            value: vec![MessageType::DHCPOFFER.into()],
        });
        offer
            .options
            .push(ConfigOption { code: OptionCode::ServerId, value: vec![192, 168, 1, 1] });
        offer.options.push(ConfigOption { code: OptionCode::Router, value: vec![192, 168, 1, 1] });
        offer.options.push(ConfigOption {
            code: OptionCode::NameServer,
            value: vec![8, 8, 8, 8, 8, 8, 4, 4],
        });
        offer
            .options
            .push(ConfigOption { code: OptionCode::RenewalTime, value: vec![0, 0, 0, 50] });
        offer
            .options
            .push(ConfigOption { code: OptionCode::RebindingTime, value: vec![0, 0, 0, 25] });
        offer
    }

    fn new_test_request() -> Message {
        let mut req = Message::new();
        req.xid = 42;

        req.chaddr = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
        req.options
            .push(ConfigOption { code: OptionCode::RequestedIpAddr, value: vec![192, 168, 1, 2] });
        req.options.push(ConfigOption {
            code: OptionCode::DhcpMessageType,
            value: vec![MessageType::DHCPREQUEST.into()],
        });
        req.options.push(ConfigOption { code: OptionCode::ServerId, value: vec![192, 168, 1, 1] });
        req
    }

/*
    fn new_test_request_with_no_requested_address() -> Message {
        let mut req = Message::new();
        req.xid = 42;

        req.chaddr = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
        req.options.push(ConfigOption {
            code: OptionCode::DhcpMessageType,
            value: vec![MessageType::DHCPREQUEST.into()],
        });
        req.options.push(ConfigOption { code: OptionCode::ServerId, value: vec![192, 168, 1, 1] });
        req
    }
*/



    fn new_test_client_ack() -> Message {
        let mut client_ack = Message::new();
        client_ack.op = OpCode::BOOTREQUEST;
        client_ack.xid = 42;
        client_ack.chaddr = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
        client_ack.options.push(ConfigOption {
            code: OptionCode::DhcpMessageType,
            value: vec![MessageType::DHCPACK.into()],
        });
        client_ack
        // Skipping other option settings as they are not needed
    }

   fn new_test_ack() -> Message {
       let mut ack = Message::new();
       ack.op = OpCode::BOOTREPLY;
       ack.xid = 42;
       ack.yiaddr = Ipv4Addr::new(192, 168, 1, 2);
       ack.chaddr = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
       ack.options
           .push(ConfigOption { code: OptionCode::IpAddrLeaseTime, value: vec![0, 0, 0, 100] });
       ack.options.push(ConfigOption {
           code: OptionCode::SubnetMask,
           value: SubnetMask::try_from(24).unwrap().octets().to_vec(),
       });
       ack.options.push(ConfigOption {
           code: OptionCode::DhcpMessageType,
           value: vec![MessageType::DHCPACK.into()],
       });
       ack.options.push(ConfigOption { code: OptionCode::ServerId, value: vec![192, 168, 1, 1] });
       ack.options.push(ConfigOption { code: OptionCode::Router, value: vec![192, 168, 1, 1] });
       ack.options.push(ConfigOption {
           code: OptionCode::NameServer,
           value: vec![8, 8, 8, 8, 8, 8, 4, 4],
       });
       ack.options.push(ConfigOption { code: OptionCode::RenewalTime, value: vec![0, 0, 0, 50] });
       ack.options
           .push(ConfigOption { code: OptionCode::RebindingTime, value: vec![0, 0, 0, 25] });
       ack
   }

    fn new_test_client_nak() -> Message {
        let mut client_nak = Message::new();
        client_nak.op = OpCode::BOOTREQUEST;
        client_nak.xid = 42;
        client_nak.chaddr = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
        client_nak.options.push(ConfigOption {
            code: OptionCode::DhcpMessageType,
            value: vec![MessageType::DHCPNAK.into()],
        });
        client_nak
    }

   fn new_test_nak() -> Message {
       let mut nak = Message::new();
       nak.op = OpCode::BOOTREPLY;
       nak.xid = 42;
       nak.chaddr = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
       nak.options.push(ConfigOption {
           code: OptionCode::DhcpMessageType,
           value: vec![MessageType::DHCPNAK.into()],
       });
       nak.options.push(ConfigOption { code: OptionCode::ServerId, value: vec![192, 168, 1, 1] });
       nak
   }

       fn new_test_release() -> Message {
           let mut release = Message::new();
           release.xid = 42;
           release.ciaddr = Ipv4Addr::new(192, 168, 1, 2);
           release.chaddr = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
           release.options.push(ConfigOption {
               code: OptionCode::DhcpMessageType,
               value: vec![MessageType::DHCPRELEASE.into()],
           });
           release
       }

       fn new_test_inform() -> Message {
           let mut inform = Message::new();
           inform.xid = 42;
           inform.ciaddr = Ipv4Addr::new(192, 168, 1, 2);
           inform.chaddr = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
           inform.options.push(ConfigOption {
               code: OptionCode::DhcpMessageType,
               value: vec![MessageType::DHCPINFORM.into()],
           });
           inform
       }

       fn new_test_inform_ack() -> Message {
           let mut ack = Message::new();
           ack.op = OpCode::BOOTREPLY;
           ack.xid = 42;
           ack.ciaddr = Ipv4Addr::new(192, 168, 1, 2);
           ack.chaddr = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
           ack.options.push(ConfigOption {
               code: OptionCode::DhcpMessageType,
               value: vec![MessageType::DHCPINFORM.into()],
           });
           ack.options.push(ConfigOption { code: OptionCode::ServerId, value: vec![192, 168, 1, 1] });
           ack.options.push(ConfigOption { code: OptionCode::Router, value: vec![192, 168, 1, 1] });
           ack.options.push(ConfigOption {
               code: OptionCode::NameServer,
               value: vec![8, 8, 8, 8, 8, 8, 4, 4],
           });
           ack
       }

       fn new_test_decline() -> Message {
           let mut decline = Message::new();
           decline.xid = 42;
           decline.chaddr = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
           decline.options.push(ConfigOption {
               code: OptionCode::DhcpMessageType,
               value: vec![MessageType::DHCPDECLINE.into()],
           });
           decline
               .options
               .push(ConfigOption { code: OptionCode::RequestedIpAddr, value: vec![192, 168, 1, 2] });
           decline
               .options
               .push(ConfigOption { code: OptionCode::ServerId, value: vec![192, 168, 1, 1] });
           decline
       }

    #[test]
    //TODO: Done
    fn test_dispatch_with_discover_returns_correct_response() {
        let disc = new_test_discover();

        let mut server = new_test_server(|| 42);
        let got = server.dispatch(disc).unwrap();

        let want = new_test_offer();

        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_discover_updates_server_state() {
        let disc = new_test_discover();
        let mac_addr = disc.chaddr;
        let mut server = new_test_server(|| 42);
        let _ = server.dispatch(disc).unwrap();

        assert_eq!(server.pool.available_addrs.len(), 0);
        assert_eq!(server.pool.allocated_addrs.len(), 1);
        assert_eq!(server.cache.len(), 1);
        let want_config = server.cache.get(&mac_addr).unwrap();
        assert_eq!(want_config.client_addr, Ipv4Addr::new(192, 168, 1, 2));
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_discover_client_binding_returns_bound_addr() {
        let disc = new_test_discover();
        let mut server = new_test_server(|| 42);
        let mut client_config = CachedConfig::default();
        let client_addr = Ipv4Addr::new(192, 168, 1, 42);
        client_config.client_addr = client_addr;
        server.pool.allocated_addrs.insert(client_addr);
        server.cache.insert(disc.chaddr, client_config);

        let got = server.dispatch(disc).unwrap();

        let mut want = new_test_offer();
        want.yiaddr = Ipv4Addr::new(192, 168, 1, 42);

        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_discover_client_binding_returns_error_when_addr_previously_not_bound() {
        let disc = new_test_discover();
        let mut server = new_test_server(|| 42);
        let mut client_config = CachedConfig::default();
        let client_addr = Ipv4Addr::new(192, 168, 1, 42);
        client_config.client_addr = client_addr;
        server.cache.insert(disc.chaddr, client_config);

        let got = server.dispatch(disc);

        let want = Err(ServerError::ServerAddressPoolFailure(AddressPoolError::UnallocatedIpv4AddrRelease(client_addr)));

        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_discover_expired_client_binding_returns_available_old_addr() {
        let disc = new_test_discover();
        let mut server = new_test_server(|| 42);
        let mut client_config = CachedConfig::default();
        client_config.client_addr = Ipv4Addr::new(192, 168, 1, 42);
        client_config.expiration = 0;
        server.cache.insert(disc.chaddr, client_config);
        server.pool.available_addrs.insert(Ipv4Addr::new(192, 168, 1, 42));

        let got = server.dispatch(disc).unwrap();

        let mut want = new_test_offer();
        want.yiaddr = Ipv4Addr::new(192, 168, 1, 42);

        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_discover_unavailable_expired_client_binding_returns_new_addr() {
        let disc = new_test_discover();
        let mut server = new_test_server(|| 42);
        let mut client_config = CachedConfig::default();
        client_config.client_addr = Ipv4Addr::new(192, 168, 1, 42);
        client_config.expiration = 0;
        server.cache.insert(disc.chaddr, client_config);
        server.pool.available_addrs.insert(Ipv4Addr::new(192, 168, 1, 2));
        server.pool.allocated_addrs.insert(Ipv4Addr::new(192, 168, 1, 42));

        let got = server.dispatch(disc).unwrap();

        let mut want = new_test_offer();
        want.yiaddr = Ipv4Addr::new(192, 168, 1, 2);

        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_discover_expired_client_binding_returns_available_requested_addr() {
        let mut disc = new_test_discover();
        disc.options
            .push(ConfigOption { code: OptionCode::RequestedIpAddr, value: vec![192, 168, 1, 2] });
        let mut server = new_test_server(|| 42);
        let mut client_config = CachedConfig::default();
        client_config.client_addr = Ipv4Addr::new(192, 168, 1, 42);
        client_config.expiration = 0;
        server.cache.insert(disc.chaddr, client_config);

        let got = server.dispatch(disc).unwrap();

        let want = new_test_offer();

        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_discover_expired_client_binding_returns_next_addr_for_unavailable_requested_addr() {
        let mut disc = new_test_discover();
        disc.options
            .push(ConfigOption { code: OptionCode::RequestedIpAddr, value: vec![192, 168, 1, 3] });
        let mut server = new_test_server(|| 42);
        let mut client_config = CachedConfig::default();
        client_config.client_addr = Ipv4Addr::new(192, 168, 1, 42);
        client_config.expiration = 0;
        server.cache.insert(disc.chaddr, client_config);

        let got = server.dispatch(disc).unwrap();

        let want = new_test_offer();

        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_discover_expired_client_binding_returns_next_addr_for_bad_requested_addr() {
        let mut disc = new_test_discover();
        disc.options
            .push(ConfigOption { code: OptionCode::RequestedIpAddr, value: vec![192, 168, 1] });
        let mut server = new_test_server(|| 42);
        let mut client_config = CachedConfig::default();
        client_config.client_addr = Ipv4Addr::new(192, 168, 1, 42);
        client_config.expiration = 0;
        server.cache.insert(disc.chaddr, client_config);

        let got = server.dispatch(disc).unwrap();

        let want = new_test_offer();

        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_discover_available_requested_addr_returns_requested_addr() {
        let mut disc = new_test_discover();
        disc.options
            .push(ConfigOption { code: OptionCode::RequestedIpAddr, value: vec![192, 168, 1, 3] });

        let mut server = new_test_server(|| 42);
        server.pool.available_addrs.insert(Ipv4Addr::new(192, 168, 1, 2));
        server.pool.available_addrs.insert(Ipv4Addr::new(192, 168, 1, 3));
        let got = server.dispatch(disc).unwrap();

        let mut want = new_test_offer();

        want.yiaddr = Ipv4Addr::new(192, 168, 1, 3);

        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_discover_unavailable_requested_addr_returns_next_addr() {
        let mut disc = new_test_discover();
        disc.options
            .push(ConfigOption { code: OptionCode::RequestedIpAddr, value: vec![192, 168, 1, 42] });

        let mut server = new_test_server(|| 42);
        server.pool.available_addrs.insert(Ipv4Addr::new(192, 168, 1, 2));
        server.pool.available_addrs.insert(Ipv4Addr::new(192, 168, 1, 3));
        server.pool.allocated_addrs.insert(Ipv4Addr::new(192, 168, 1, 42));
        let got = server.dispatch(disc).unwrap();

        let mut want = new_test_offer();
        want.yiaddr = Ipv4Addr::new(192, 168, 1, 2);
        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_discover_unavailable_requested_addr_no_available_addr_returns_error() {
        let mut disc = new_test_discover();
        disc.options
            .push(ConfigOption { code: OptionCode::RequestedIpAddr, value: vec![192, 168, 1, 42] });

        let mut server = new_test_server(|| 42);
        server.pool.available_addrs.clear();
        server.pool.allocated_addrs.insert(Ipv4Addr::new(192, 168, 1, 42));
        let got = server.dispatch(disc);

        let want : Result<Message, ServerError> = Err(ServerError::ServerAddressPoolFailure(AddressPoolError::Ipv4AddrExhaustion));
        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_discover_no_requested_addr_no_available_addr_returns_error() {
        let disc = new_test_discover();
        let mut server = new_test_server(|| 42);

        server.pool.available_addrs.clear();
        let got = server.dispatch(disc);

        let want : Result<Message, ServerError> = Err(ServerError::ServerAddressPoolFailure(AddressPoolError::Ipv4AddrExhaustion));
        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_client_offer_message_returns_error() {
        let client_offer = new_test_client_offer();

        let mut server = new_test_server(|| 42);

        let got = server.dispatch(client_offer);

        let want : Result<Message, ServerError> = Err(ServerError::InvalidClientMessage(MessageType::DHCPOFFER));
        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_client_ack_message_returns_error() {
        let client_ack = new_test_client_ack();

        let mut server = new_test_server(|| 42);

        let got = server.dispatch(client_ack);

        let want : Result<Message, ServerError> = Err(ServerError::InvalidClientMessage(MessageType::DHCPACK));
        assert_eq!(got, want);
    }

    #[test]
    //TODO: Done
    fn test_dispatch_with_client_nak_message_returns_error() {
        let client_nak = new_test_client_nak();

        let mut server = new_test_server(|| 42);

        let got = server.dispatch(client_nak);

        let want : Result<Message, ServerError> = Err(ServerError::InvalidClientMessage(MessageType::DHCPNAK));

        assert_eq!(got, want);
    }

    #[test]
    fn test_dispatch_with_selecting_request_valid_selecting_request_returns_ack() {
        let mut req = new_test_request();
        let requested_ip_addr = Ipv4Addr::new(192, 168, 1, 2);
        req.ciaddr = requested_ip_addr;
        req.options.remove(0);

        let mut server = new_test_server(|| 42);
        server.cache.insert(
            req.chaddr,
            CachedConfig {
                client_addr: requested_ip_addr,
                options: vec![],
                expiration: std::i64::MAX,
            },
        );

        let _ = server.pool.allocate_addr(requested_ip_addr);

        let got = server.dispatch(req).unwrap();

        let mut want = new_test_ack();
        want.ciaddr = requested_ip_addr;
        assert_eq!(got, want);
    }

    #[test]
    fn test_dispatch_with_selecting_request_wrong_server_id_returns_error() {
        let mut req = new_test_request();
        let requested_ip_addr = Ipv4Addr::new(192, 168, 1, 2);
        req.ciaddr = requested_ip_addr;
        req.options.remove(0);

        let mut server = new_test_server(|| 42);
        server.cache.insert(
            req.chaddr,
            CachedConfig {
                client_addr: requested_ip_addr,
                options: vec![],
                expiration: std::i64::MAX,
            },
        );
        let _ = server.pool.allocate_addr(requested_ip_addr);

        server.config.server_ip = Ipv4Addr::new(1, 2, 3, 4);
        let got = server.dispatch(req);

        let want = Err(ServerError::UnwantedDHCPServer);
        assert_eq!(got, want);
    }

    #[test]
    fn test_dispatch_with_selecting_request_mismatched_requested_addr_returns_error() {
        let mut req = new_test_request();
        req.ciaddr = Ipv4Addr::new(192, 168, 1, 2);
        req.options.remove(0);

        let mut server = new_test_server(|| 42);
        let requested_ip_addr = Ipv4Addr::new(192, 168, 1, 3);
        server.cache.insert(
            req.chaddr,
            CachedConfig {
                client_addr: requested_ip_addr,
                options: vec![],
                expiration: std::i64::MAX,
            },
        );

        let _ = server.pool.allocate_addr(requested_ip_addr);

        let got = server.dispatch(req);

        let want = Err(ServerError::RequestedAddrAssignmentFailure("Requested Ipv4 address does not match initial address requested in discovery".to_owned()));

        assert_eq!(got, want);
    }

    #[test]
    fn test_dispatch_with_selecting_request_expired_config_returns_error() {
        let mut req = new_test_request();
        req.ciaddr = Ipv4Addr::new(192, 168, 1, 2);
        req.options.remove(0);

        let mut server = new_test_server(|| 42);
        let requested_ip_addr = Ipv4Addr::new(192, 168, 1, 2);
        server.cache.insert(
            req.chaddr,
            CachedConfig {
                client_addr: requested_ip_addr,
                options: vec![],
                expiration: 0,
            },
        );

        let _ = server.pool.allocate_addr(requested_ip_addr);

        let got = server.dispatch(req);

        let want = Err(ServerError::RequestedAddrAssignmentFailure("Client Config has expired".to_owned()));

        assert_eq!(got, want);
    }

    #[test]
    fn test_dispatch_with_selecting_request_failed_addr_allocation_returns_error() {
        let mut req = new_test_request();
        req.ciaddr = Ipv4Addr::new(192, 168, 1, 2);
        req.options.remove(0);

        let mut server = new_test_server(|| 42);
        let requested_ip_addr = Ipv4Addr::new(192, 168, 1, 2);
        server.cache.insert(
            req.chaddr,
            CachedConfig {
                client_addr: requested_ip_addr,
                options: vec![],
                expiration: std::i64::MAX,
            },
        );

        let got = server.dispatch(req);

        let want = Err(ServerError::RequestedAddrAssignmentFailure("Server failed to reserve requested Ipv4 adddress".to_owned()));

        assert_eq!(got, want);
    }

    #[test]
    fn test_dispatch_with_selecting_request_no_client_config_returns_error() {
        let mut req = new_test_request();
        req.ciaddr = Ipv4Addr::new(192, 168, 1, 2);
        req.options.remove(0);

        let mut server = new_test_server(|| 42);
        let got = server.dispatch(req);

        let want = Err(ServerError::RequestedAddrAssignmentFailure("Could not retrieve client config".to_owned()));

        assert_eq!(got, want);
    }

    #[test]
    fn test_dispatch_with_selecting_request_valid_selecting_request_maintains_server_invariants() {
        let requested_ip_addr = Ipv4Addr::new(192, 168, 1, 2);
        let mut req = new_test_request();
        req.ciaddr = requested_ip_addr;
        req.options.remove(0);

        let mut server = new_test_server(|| 42);
        server.cache.insert(
            req.chaddr,
            CachedConfig {
                client_addr: requested_ip_addr,
                options: vec![],
                expiration: std::i64::MAX,
            },
        );
        let _ = server.pool.allocate_addr(requested_ip_addr);

        let _ = server.dispatch(req.clone()).unwrap();

        assert!(server.cache.contains_key(&req.chaddr));
        assert!(server.pool.addr_is_allocated(requested_ip_addr));
    }

    #[test]
    fn test_dispatch_with_selecting_request_no_address_allocation_maintains_server_invariants() {
        let requested_ip_addr = Ipv4Addr::new(192, 168, 1, 2);
        let mut req = new_test_request();
        req.ciaddr = requested_ip_addr;
        req.options.remove(0);

        let mut server = new_test_server(|| 42);
        let _ = server.dispatch(req.clone());

        assert!(!server.cache.contains_key(&req.chaddr));
        assert!(!server.pool.addr_is_allocated(Ipv4Addr::new(192, 168, 1, 2)));
    }

    #[test]
    fn test_dispatch_with_init_boot_request_correct_address_returns_ack() {
        let mut req = new_test_request();
        req.options.remove(2);
        let requested_ip_addr = get_requested_ip_addr(&req).unwrap();

        let mut server = new_test_server(|| 42);
        server.cache.insert(
            req.chaddr,
            CachedConfig {
                client_addr: requested_ip_addr,
                options: vec![],
                expiration: std::i64::MAX,
            },
        );
        let _ = server.pool.allocate_addr(requested_ip_addr);

        let got = server.dispatch(req).unwrap();

        let want = new_test_ack();
        assert_eq!(got, want);
    }

    #[test]
    fn test_dispatch_with_init_boot_request_incorrect_address_returns_nak() {
        let mut req = new_test_request();
        req.options.remove(0);
        req.options.remove(1);
        req.options
            .push(ConfigOption { code: OptionCode::RequestedIpAddr, value: vec![192, 168, 1, 42] });

        let mut server = new_test_server(|| 42);
        let assigned_ip = Ipv4Addr::new(192, 168, 1, 2);
        server.cache.insert(
            req.chaddr,
            CachedConfig { client_addr: assigned_ip, options: vec![], expiration: std::i64::MAX },
        );
        let _ = server.pool.allocate_addr(assigned_ip);

        let got = server.dispatch(req).unwrap();

        let want = new_test_nak();
        assert_eq!(got, want);
    }

    #[test]
    fn test_dispatch_with_init_boot_request_unknown_client_returns_error() {
        let mut req = new_test_request();
        req.options.remove(2);

        let mut server = new_test_server(|| 42);
        let got = server.dispatch(req);

        let want = Err(ServerError::UnknownClientMac);

        assert_eq!(got, want);
    }

    #[test]
    fn test_dispatch_with_init_boot_request_client_on_wrong_subnet_returns_nak() {
        let mut req = new_test_request();
        req.options.remove(0);
        req.options.remove(1);
        req.options
            .push(ConfigOption { code: OptionCode::RequestedIpAddr, value: vec![10, 0, 0, 1] });

        let mut server = new_test_server(|| 42);
        let got = server.dispatch(req).unwrap();

        let want = new_test_nak();
        assert_eq!(got, want);
    }

    #[test]
    fn test_dispatch_with_renewing_request_valid_request_returns_ack() {
        let mut req = new_test_request();
        req.options.remove(0);
        req.options.remove(1);
        let client_ip = Ipv4Addr::new(192, 168, 1, 2);
        req.ciaddr = client_ip;

        let mut server = new_test_server(|| 42);
        server.cache.insert(
            req.chaddr,
            CachedConfig { client_addr: client_ip, options: vec![], expiration: std::i64::MAX },
        );
        let _ = server.pool.allocate_addr(client_ip);

        let got = server.dispatch(req).unwrap();

        let mut want = new_test_ack();
        want.ciaddr = client_ip;
        assert_eq!(got, want);
    }

    #[test]
    fn test_dispatch_with_renewing_request_unknown_client_returns_error() {
        let mut req = new_test_request();
        req.options.remove(0);
        req.options.remove(1);
        let client_ip = Ipv4Addr::new(192, 168, 1, 2);
        req.ciaddr = client_ip;

        let mut server = new_test_server(|| 42);
        let got = server.dispatch(req);

        let want = Err(ServerError::RequestedAddrAssignmentFailure("Could not retrieve client config".to_owned()));

        assert_eq!(got, want);
    }

    #[test]
    fn test_dispatch_with_unknown_client_state_returns_error() {
        let mut req = new_test_request();
        req.options.remove(0);
        req.options.remove(1);

        let mut server = new_test_server(|| 42);
        let got = server.dispatch(req);

        let want = Err(ServerError::UnknownClientStatAtReboot);

        assert_eq!(got, want);
    }

    #[test]
    fn test_get_client_state_with_selecting_returns_selecting() {
        let mut msg = new_test_request();
        msg.ciaddr = Ipv4Addr::new(192, 168, 1, 2);
        msg.options.remove(0);

        let got = get_client_state(&msg);

        assert_eq!(got, ClientState::Selecting);
    }

    #[test]
    fn test_get_client_state_with_initreboot_returns_initreboot() {
        let mut msg = new_test_request();
        msg.options.remove(2);

        let got = get_client_state(&msg);

        assert_eq!(got, ClientState::InitReboot);
    }

    #[test]
    fn test_get_client_state_with_renewing_returns_renewing() {
        let mut msg = new_test_request();
        msg.options.remove(0);
        msg.options.remove(1);
        msg.ciaddr = Ipv4Addr::new(1, 2, 3, 4);

        let got = get_client_state(&msg);

        assert_eq!(got, ClientState::Renewing);
    }

    #[test]
    fn test_get_client_state_with_unknown_returns_unknown() {
        let mut msg = new_test_request();
        msg.options.clear();

        let got = get_client_state(&msg);

        assert_eq!(got, ClientState::Unknown);
    }

    #[test]
    fn test_dispatch_with_unknown_client_msg_returns_error() {
        let mut msg = new_test_request();
        msg.options.clear();

        let mut server = new_test_server(|| 42);
        let got = server.dispatch(msg);

        let want = Err(ServerError::UnknownClientRequest);

        assert_eq!(got, want);
    }

    #[test]
    fn test_release_expired_leases_with_none_expired_releases_none() {
        let mut server = new_test_server(|| 42);
        server.pool.available_addrs.clear();
        server.cache.insert(
            MacAddr { octets: [0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA] },
            CachedConfig {
                client_addr: Ipv4Addr::new(192, 168, 1, 2),
                options: vec![],
                expiration: std::i64::MAX,
            },
        );
        server.pool.allocated_addrs.insert(Ipv4Addr::new(192, 168, 1, 2));
        server.cache.insert(
            MacAddr { octets: [0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB] },
            CachedConfig {
                client_addr: Ipv4Addr::new(192, 168, 1, 3),
                options: vec![],
                expiration: std::i64::MAX,
            },
        );
        server.pool.allocated_addrs.insert(Ipv4Addr::new(192, 168, 1, 3));
        server.cache.insert(
            MacAddr { octets: [0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC] },
            CachedConfig {
                client_addr: Ipv4Addr::new(192, 168, 1, 4),
                options: vec![],
                expiration: std::i64::MAX,
            },
        );
        server.pool.allocated_addrs.insert(Ipv4Addr::new(192, 168, 1, 4));

        server.release_expired_leases();

        assert_eq!(server.cache.len(), 3);
        assert_eq!(server.pool.available_addrs.len(), 0);
        assert_eq!(server.pool.allocated_addrs.len(), 3);
    }

    #[test]
    fn test_release_expired_leases_with_all_expired_releases_all() {
        let mut server = new_test_server(|| 42);
        server.pool.available_addrs.clear();
        server.cache.insert(
            MacAddr { octets: [0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA] },
            CachedConfig {
                client_addr: Ipv4Addr::new(192, 168, 1, 2),
                options: vec![],
                expiration: 0,
            },
        );
        server.pool.allocated_addrs.insert(Ipv4Addr::new(192, 168, 1, 2));
        server.cache.insert(
            MacAddr { octets: [0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB] },
            CachedConfig {
                client_addr: Ipv4Addr::new(192, 168, 1, 3),
                options: vec![],
                expiration: 0,
            },
        );
        server.pool.allocated_addrs.insert(Ipv4Addr::new(192, 168, 1, 3));
        server.cache.insert(
            MacAddr { octets: [0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC] },
            CachedConfig {
                client_addr: Ipv4Addr::new(192, 168, 1, 4),
                options: vec![],
                expiration: 0,
            },
        );
        server.pool.allocated_addrs.insert(Ipv4Addr::new(192, 168, 1, 4));

        server.release_expired_leases();

        assert_eq!(server.cache.len(), 0);
        assert_eq!(server.pool.available_addrs.len(), 3);
        assert_eq!(server.pool.allocated_addrs.len(), 0);
    }

    #[test]
    fn test_release_expired_leases_with_some_expired_releases_expired() {
        let mut server = new_test_server(|| 42);
        server.pool.available_addrs.clear();
        server.cache.insert(
            MacAddr { octets: [0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA] },
            CachedConfig {
                client_addr: Ipv4Addr::new(192, 168, 1, 2),
                options: vec![],
                expiration: std::i64::MAX,
            },
        );
        server.pool.allocated_addrs.insert(Ipv4Addr::new(192, 168, 1, 2));
        server.cache.insert(
            MacAddr { octets: [0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB] },
            CachedConfig {
                client_addr: Ipv4Addr::new(192, 168, 1, 3),
                options: vec![],
                expiration: 0,
            },
        );
        server.pool.allocated_addrs.insert(Ipv4Addr::new(192, 168, 1, 3));
        server.cache.insert(
            MacAddr { octets: [0xCC, 0xCC, 0xCC, 0xCC, 0xCC, 0xCC] },
            CachedConfig {
                client_addr: Ipv4Addr::new(192, 168, 1, 4),
                options: vec![],
                expiration: std::i64::MAX,
            },
        );
        server.pool.allocated_addrs.insert(Ipv4Addr::new(192, 168, 1, 4));

        server.release_expired_leases();

        assert_eq!(server.cache.len(), 2);
        assert!(!server
            .cache
            .contains_key(&MacAddr { octets: [0xBB, 0xBB, 0xBB, 0xBB, 0xBB, 0xBB] }));
        assert_eq!(server.pool.available_addrs.len(), 1);
        assert_eq!(server.pool.allocated_addrs.len(), 2);
    }

    #[test]
    fn test_dispatch_with_known_release() {
        let release = new_test_release();
        let mut server = new_test_server(|| 42);
        let client_ip = Ipv4Addr::new(192, 168, 1, 2);
        let _ = server.pool.allocate_addr(client_ip);
        let client_mac = MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] };
        let client_config =
            CachedConfig { client_addr: client_ip, options: vec![], expiration: std::i64::MAX };
        server.cache.insert(client_mac, client_config.clone());

        let got = server.dispatch(release);

        assert!(got.is_err(), "server returned a Message value");
        assert!(!server.pool.addr_is_allocated(client_ip), "server did not free client address");
        assert!(server.pool.addr_is_available(client_ip), "server did not free client address");
        assert!(
            server.cache.contains_key(&client_mac),
            "server did not retain cached client settings"
        );
        assert_eq!(
            server.cache.get(&client_mac).unwrap(),
            &client_config,
            "server did not retain cached client settings"
        );
    }

    #[test]
    fn test_dispatch_with_unknown_release() {
        let release = new_test_release();
        let mut server = new_test_server(|| 42);
        let client_ip = Ipv4Addr::new(192, 168, 1, 2);
        let _ = server.pool.allocate_addr(client_ip);
        let cached_mac = MacAddr { octets: [0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA] };
        let client_config =
            CachedConfig { client_addr: client_ip, options: vec![], expiration: std::i64::MAX };
        server.cache.insert(cached_mac, client_config.clone());

        let got = server.dispatch(release);

        assert!(got.is_err(), "server returned a Message value");
        assert!(server.pool.addr_is_allocated(client_ip), "server did not free client address");
        assert!(!server.pool.addr_is_available(client_ip), "server did not free client address");
        assert!(
            server.cache.contains_key(&cached_mac),
            "server did not retain cached client settings"
        );
        assert_eq!(
            server.cache.get(&cached_mac).unwrap(),
            &client_config,
            "server did not retain cached client settings"
        );
    }

    #[test]
    fn test_dispatch_with_inform_returns_ack() {
        let inform = new_test_inform();
        let mut server = new_test_server(|| 42);

        let got = server.dispatch(inform).unwrap();

        let want = new_test_inform_ack();

        assert_eq!(got, want, "expected: {:?}\ngot: {:?}", want, got);
    }

    #[test]
    fn test_dispatch_with_decline_marks_addr_allocated() {
        let decline = new_test_decline();
        let mut server = new_test_server(|| 42);
        let already_used_ip = Ipv4Addr::new(192, 168, 1, 2);
        server.config.managed_addrs.push(already_used_ip);
        let client_config = CachedConfig {
            client_addr: already_used_ip,
            options: vec![],
            expiration: std::i64::MAX,
        };
        server.cache.insert(decline.chaddr, client_config);

        let got = server.dispatch(decline);

        assert!(got.is_err(), "server returned a Message value");
        assert!(!server.pool.addr_is_available(already_used_ip), "addr still marked available");
        assert!(server.pool.addr_is_allocated(already_used_ip), "addr not marked allocated");
        assert!(
            !server.cache.contains_key(&MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] }),
            "client config retained"
        );
    }

    #[test]
    fn test_client_requested_lease_time() {
        let mut disc = new_test_discover();
        disc.options
            .push(ConfigOption { code: OptionCode::IpAddrLeaseTime, value: vec![0, 0, 0, 20] });

        let mut server = new_test_server(|| 42);
        let result = server.dispatch(disc).unwrap();
        assert_eq!(
            BigEndian::read_u32(
                &result.get_config_option(OptionCode::IpAddrLeaseTime).unwrap().value
            ),
            20
        );

        let cached_config =
            server.cache.get(&MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] }).unwrap();
        assert_eq!(cached_config.expiration, 42 + 20);
    }

    #[test]
    fn test_client_requested_lease_time_greater_than_max() {
        let mut disc = new_test_discover();
        disc.options
            .push(ConfigOption { code: OptionCode::IpAddrLeaseTime, value: vec![0, 0, 0, 20] });

        let mut server = new_test_server(|| 42);
        server.config.max_lease_time_s = 10;
        let result = server.dispatch(disc).unwrap();
        assert_eq!(
            BigEndian::read_u32(
                &result.get_config_option(OptionCode::IpAddrLeaseTime).unwrap().value
            ),
            10
        );

        let cached_config =
            server.cache.get(&MacAddr { octets: [0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF] }).unwrap();
        assert_eq!(cached_config.expiration, 42 + 10);
    }

/*    #[test]
    fn test_add_msg_nak() {
        let mut nak = new_test_nak();
        let s = String::from("hello world");
        add_request_nak_message(&mut nak, s);
        println!("This is NAK - {:?}", nak);
        let v = nak.get_config_option(OptionCode::Message).unwrap();
        let s2 = v.to_owned().value;
        let str = from_utf8(&s2);
        println!("This is the text - {:?}", str)


    }*/
}
