#![allow(dead_code)]

#[cfg(feature = "log")]
use env_logger::Builder;
use getopts::{Matches, Options};
#[cfg(feature = "log")]
use log::{trace, Level, LevelFilter};
use std::env;
use std::fs::File;
use std::io::{self, Write};
use std::process;
use std::str::{self, FromStr};
use std::time::{SystemTime, UNIX_EPOCH};

#[cfg(feature = "phy-tuntap_interface")]
use smoltcp::phy::TunTapInterface;
use smoltcp::phy::{Device, FaultInjector, Medium, Tracer};
use smoltcp::phy::{PcapMode, PcapWriter};
use smoltcp::time::{Duration, Instant};

#[cfg(feature = "log")]
pub fn setup_logging_with_clock<F>(filter: &str, since_startup: F)
where
    F: Fn() -> Instant + Send + Sync + 'static,
{
    Builder::new()
        .format(move |buf, record| {
            let elapsed = since_startup();
            let timestamp = format!("[{elapsed}]");
            if record.target().starts_with("smoltcp::") {
                writeln!(
                    buf,
                    "\x1b[0m{} ({}): {}\x1b[0m",
                    timestamp,
                    record.target().replace("smoltcp::", ""),
                    record.args()
                )
            } else if record.level() == Level::Trace {
                let message = format!("{}", record.args());
                writeln!(
                    buf,
                    "\x1b[37m{} {}\x1b[0m",
                    timestamp,
                    message.replace('\n', "\n             ")
                )
            } else {
                writeln!(
                    buf,
                    "\x1b[32m{} ({}): {}\x1b[0m",
                    timestamp,
                    record.target(),
                    record.args()
                )
            }
        })
        .filter(None, LevelFilter::Trace)
        .parse_filters(filter)
        .parse_env("RUST_LOG")
        .init();
}

#[cfg(feature = "log")]
pub fn setup_logging(filter: &str) {
    setup_logging_with_clock(filter, Instant::now)
}

pub fn create_options() -> (Options, Vec<&'static str>) {
    let mut opts = Options::new();
    opts.optflag("h", "help", "print this help menu");
    (opts, Vec::new())
}

pub fn parse_options(options: &Options, free: Vec<&str>) -> Matches {
    match options.parse(env::args().skip(1)) {
        Err(err) => {
            println!("{err}");
            process::exit(1)
        }
        Ok(matches) => {
            if matches.opt_present("h") || matches.free.len() != free.len() {
                let brief = format!(
                    "Usage: {} [OPTION]... {}",
                    env::args().next().unwrap(),
                    free.join(" ")
                );
                print!("{}", options.usage(&brief));
                process::exit((matches.free.len() != free.len()) as _);
            }
            matches
        }
    }
}

pub fn add_tuntap_options(opts: &mut Options, _free: &mut [&str]) {
    opts.optopt("", "tun", "TUN interface to use", "tun0");
    opts.optopt("", "tap", "TAP interface to use", "tap0");
}

#[cfg(feature = "phy-tuntap_interface")]
pub fn parse_tuntap_options(matches: &mut Matches) -> TunTapInterface {
    let tun = matches.opt_str("tun");
    let tap = matches.opt_str("tap");
    match (tun, tap) {
        (Some(tun), None) => TunTapInterface::new(&tun, Medium::Ip).unwrap(),
        (None, Some(tap)) => TunTapInterface::new(&tap, Medium::Ethernet).unwrap(),
        _ => panic!("You must specify exactly one of --tun or --tap"),
    }
}

pub fn add_middleware_options(opts: &mut Options, _free: &mut [&str]) {
    opts.optopt("", "pcap", "Write a packet capture file", "FILE");
    opts.optopt(
        "",
        "drop-chance",
        "Chance of dropping a packet (%)",
        "CHANCE",
    );
    opts.optopt(
        "",
        "corrupt-chance",
        "Chance of corrupting a packet (%)",
        "CHANCE",
    );
    opts.optopt(
        "",
        "size-limit",
        "Drop packets larger than given size (octets)",
        "SIZE",
    );
    opts.optopt(
        "",
        "tx-rate-limit",
        "Drop packets after transmit rate exceeds given limit \
                                      (packets per interval)",
        "RATE",
    );
    opts.optopt(
        "",
        "rx-rate-limit",
        "Drop packets after transmit rate exceeds given limit \
                                      (packets per interval)",
        "RATE",
    );
    opts.optopt(
        "",
        "shaping-interval",
        "Sets the interval for rate limiting (ms)",
        "RATE",
    );
}

pub fn parse_middleware_options<D>(
    matches: &mut Matches,
    device: D,
    loopback: bool,
) -> FaultInjector<Tracer<PcapWriter<D, Box<dyn io::Write>>>>
where
    D: Device,
{
    let drop_chance = matches
        .opt_str("drop-chance")
        .map(|s| u8::from_str(&s).unwrap())
        .unwrap_or(0);
    let corrupt_chance = matches
        .opt_str("corrupt-chance")
        .map(|s| u8::from_str(&s).unwrap())
        .unwrap_or(0);
    let size_limit = matches
        .opt_str("size-limit")
        .map(|s| usize::from_str(&s).unwrap())
        .unwrap_or(0);
    let tx_rate_limit = matches
        .opt_str("tx-rate-limit")
        .map(|s| u64::from_str(&s).unwrap())
        .unwrap_or(0);
    let rx_rate_limit = matches
        .opt_str("rx-rate-limit")
        .map(|s| u64::from_str(&s).unwrap())
        .unwrap_or(0);
    let shaping_interval = matches
        .opt_str("shaping-interval")
        .map(|s| u64::from_str(&s).unwrap())
        .unwrap_or(0);

    let pcap_writer: Box<dyn io::Write> = match matches.opt_str("pcap") {
        Some(pcap_filename) => Box::new(File::create(pcap_filename).expect("cannot open file")),
        None => Box::new(io::sink()),
    };

    let seed = SystemTime::now()
        .duration_since(UNIX_EPOCH)
        .unwrap()
        .subsec_nanos();

    let device = PcapWriter::new(
        device,
        pcap_writer,
        if loopback {
            PcapMode::TxOnly
        } else {
            PcapMode::Both
        },
    );

    let device = Tracer::new(device, |_timestamp, _printer| {
        #[cfg(feature = "log")]
        trace!("{}", _printer);
    });

    let mut device = FaultInjector::new(device, seed);
    device.set_drop_chance(drop_chance);
    device.set_corrupt_chance(corrupt_chance);
    device.set_max_packet_size(size_limit);
    device.set_max_tx_rate(tx_rate_limit);
    device.set_max_rx_rate(rx_rate_limit);
    device.set_bucket_interval(Duration::from_millis(shaping_interval));
    device
}
