use ip_network::Ipv4Network;
use mac_address::MacAddress;
use serde::{Deserialize, Serialize};

use super::LeaseTime;
use std::{collections::HashMap, net::Ipv4Addr, path::PathBuf};

/// All configuration for a `Leases`.
#[derive(Serialize, Deserialize, Clone, Debug)]
pub struct LeaseConfig {
    /// The path where the leases files is written to and read from.
    /// The name, however, is always the same and not configurable.
    ///
    /// This will only be used when the leases file is used.
    #[serde(skip)]
    pub leases_file_path: PathBuf,
    /// See: [LeaseTime](LeaseTime)
    pub lease_time: LeaseTime,
    /// A range of IP addresses for the server to lease. Specified in CIDR notation. For example: `10.1.9.32/16`
    pub network_cidr: Ipv4Network,
    /// The server will always assign these ip adddresses to these mac addresses.
    /// All static leases must be within the network_cidr range.
    pub static_leases: HashMap<MacAddress, Ipv4Addr>,
    /// Whether to read and write leases to a file to maintain state between server restarts.
    /// Defaults to `true` (when not in a benchmark or integration test) but you might want to set to `false` for performance, lack of storage, etc.
    pub use_leases_file: bool,
}

impl Default for LeaseConfig {
    fn default() -> Self {
        Self {
            lease_time: LeaseTime::ONE_DAY,
            network_cidr: Ipv4Network::new(Ipv4Addr::new(10, 0, 0, 0), 16).unwrap(), // 2^(32-16) addresses
            static_leases: HashMap::new(),
            use_leases_file: cfg!(all(
                not(feature = "benchmark"),
                not(feature = "integration")
            )),
            leases_file_path: PathBuf::new(), // empty, current directory
        }
    }
}
