//!
//! Provides 7 functions to return mock internet data.
//!
//! # Examples
//!
//! ```rust
//! use mockd::internet;
//!
//!     let data = internet::domain_name(); // domain_name: productvisualize.net
//!     let data = internet::http_method(); // http_method: DELETE
//!     let data = internet::domain_suffix(); // domain_suffix: biz
//!     let data = internet::ipv4_address(); // ipv4_address: 196.140.182.201
//!     let data = internet::ipv6_address(); // ipv6_address: 2001:cafe:1248:1dc7:17dd:19f4:8798:621d
//!     let data = internet::mac_address(); // mac_address: 2D:3F:7E:5D:61:C1
//!     let data = internet::username(); // username: Nienow1881
//! ```
//! # Feature
//!
//! Requires the "internet" feature.
//!

use crate::company;
use crate::job;
use crate::misc;
use crate::person::data as person_data;

pub(crate) mod data;

/// Construct a random domain name based on words in the test data dictionaries.
///
/// The domain name is constructed using:
///     <job.descriptor><company.bs>.<internet.domain_suffix>
///
/// # Example
///
/// ```rust
/// let domain_name = mockd::internet::domain_name();
///
/// println!("Domain Name: {}", domain_name);
/// ```
///
/// # Feature
///
/// Requires the "internet" feature.
///
pub fn domain_name() -> String {
    format!(
        "{}{}.{}",
        job::descriptor().to_lowercase(),
        company::bs().to_lowercase(),
        domain_suffix()
    )
}

/// Pick a random http-method from the dictionary.
///
/// # Example
///
/// ```rust
/// let http_method = mockd::internet::http_method();
///
/// println!("Http Method: {}", http_method);
/// ```
///
/// # Feature
///
/// Requires the "internet" feature.
///
pub fn http_method() -> String {
    misc::random_data(data::HTTP_METHOD).to_string()
}

/// Pick a random domain suffix from the dictionary.
///
/// # Example
///
/// ```rust
/// let domain_suffix = mockd::internet::domain_suffix();
///
/// println!("Domain suffix: {}", domain_suffix);
///
/// ```
///
/// # Feature
///
/// Requires the "internet" feature.
///
pub fn domain_suffix() -> String {
    misc::random_data(data::DOMAIN_SUFFIX).to_string()
}

/// Generate a random ipv4 address string.
///
/// # Example
///
/// ```rust
/// let ipv4 = mockd::internet::ipv4_address();
///
/// println!("IPv4 address: {}", ipv4);
///
/// ```
///
/// # Feature
///
/// Requires the "internet" feature.
///
pub fn ipv4_address() -> String {
    format!(
        "{}.{}.{}.{}",
        misc::random::<i16>(2, 254),
        misc::random::<i16>(2, 254),
        misc::random::<i16>(2, 254),
        misc::random::<i16>(2, 254),
    )
}

/// Generate a random ipv6 address string.
///
/// # Example
///
/// ```rust
/// let ipv6 = mockd::internet::ipv6_address();
///
/// println!("IPv6 address: {}", ipv6);
///
/// ```
///
/// # Feature
///
/// Requires the "internet" feature.
///
pub fn ipv6_address() -> String {
    let num: i64 = 65536;
    misc::random::<i64>(0, num);
    format!(
        "2001:cafe:{:x}:{:x}:{:x}:{:x}:{:x}:{:x}",
        misc::random::<i64>(0, num),
        misc::random::<i64>(0, num),
        misc::random::<i64>(0, num),
        misc::random::<i64>(0, num),
        misc::random::<i64>(0, num),
        misc::random::<i64>(0, num),
    )
}

/// Generate a random mac address string.
///
/// # Example
///
/// ```rust
/// let mac = mockd::internet::mac_address();
///
/// println!("MAC address: {}", mac);
///
/// ```
///
/// # Feature
///
/// Requires the "internet" feature.
///
pub fn mac_address() -> String {
    let num: i16 = 255;
    format!(
        "{:02X}:{:02X}:{:02X}:{:02X}:{:02X}:{:02X}",
        misc::random(0, num),
        misc::random(0, num),
        misc::random(0, num),
        misc::random(0, num),
        misc::random(0, num),
        misc::random(0, num),
    )
}

/// Generate a random user name.
///
/// User name is generated by picking as last name from the test dictionary
/// and appending digits to the last name. ,
///
/// # Example
///
/// ```rust
/// let username = mockd::internet::username();
///
/// println!("Username: {}", username);
///
/// ```
///
/// # Feature
///
/// Requires the "internet" feature.
///
pub fn username() -> String {
    format!(
        "{}{}",
        misc::random_data(person_data::LAST),
        misc::replace_with_numbers("####".to_string()),
    )
}

#[cfg(test)]
mod tests {
    use crate::internet;
    use crate::testify::exec_mes;

    #[test]
    fn domain_name() {
        exec_mes("internet::domain_name", internet::domain_name);
    }

    #[test]
    fn http_method() {
        exec_mes("internet::http_method", internet::http_method);
    }

    #[test]
    fn domain_suffix() {
        exec_mes("internet::domain_suffix", internet::domain_suffix);
    }

    #[test]
    fn ipv4_address() {
        exec_mes("internet::ipv4_address", internet::ipv4_address);

        let data1 = internet::ipv4_address();
        let data2 = internet::ipv4_address();
        assert_ne!(data1, data2);
    }

    #[test]
    fn ipv6_address() {
        exec_mes("internet::ipv6_address", internet::ipv6_address);

        let data1 = internet::ipv6_address();
        let data2 = internet::ipv6_address();
        assert_ne!(data1, data2);
    }

    #[test]
    fn mac_address() {
        exec_mes("internet::mac_address", internet::mac_address);

        let data1 = internet::mac_address();
        let data2 = internet::mac_address();
        assert_ne!(data1, data2);
    }

    #[test]
    fn username() {
        exec_mes("internet::username", internet::username);
    }
}
