use std::fmt::{Debug, Display, Formatter};

#[derive(Clone)]
pub struct Parameter {
    pub name: String,
    pub value: String,
}

pub type ParameterList = Vec<Parameter>;

pub fn parameter_find(params: &Vec<Parameter>, name: &str) -> Option<Parameter> {
    for param in params {
        if param.name == name {
            return Some(param.clone());
        }
    }
    None
}
pub fn parameter_list_find(param_lists: &Vec<ParameterList>, name: &str, value: &str, strict: bool) -> Option<ParameterList> {
    for params in param_lists {
        for param in params {
            if param.name != name {
                continue;
            }
            if param.value != value && strict {
                continue;
            }
            if !param.value.contains(value) && !strict {
                continue;
            }
            return Some(params.clone());
        }
    }
    None
}

pub fn parameter_parse(params_str: &str) -> ParameterList {
    let parts: Vec<&str> = params_str.split(' ').collect();

    let mut response_params = Vec::new();
    parts.iter().for_each(|part| {
        response_params.push(Parameter::from(part.split_once('=').unwrap()));
    });

    response_params
}

impl From<(&str, &str)> for Parameter {
    fn from(param: (&str, &str)) -> Parameter {
        Parameter::new(String::from(param.0), String::from(param.1))
    }
}

impl Parameter {
    pub fn new(name: String, value: String) -> Parameter {
        let value = value
            .replace("\\s", " ")
            .replace("\\p", "|");

        Parameter {
            name,
            value,
        }
    }

    pub fn to_i32(&self, default: i32) -> i32 {
        self.value.parse::<i32>().unwrap_or(default)
    }
}

impl Display for Parameter {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}={}", self.name, self.value)
    }
}

impl Debug for Parameter {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        write!(f, "{}={}", self.name, self.value)
    }
}

impl Default for Parameter {
    fn default() -> Self {
        Parameter::new(String::from(""), String::from(""))
    }
}