use std::{fs,env,error::Error};

struct Config {
    query: String,
    file_path: String,
}

impl Config{
    fn new(args: &[String])->Result<Config,&'static str>{
       if args.len() < 3{
         return  Err("not enough arguments")
       } 
       let query = args[1].clone();
       let file_path = args[2].clone();
    
       Ok(Config{
           query,
           file_path
       })
    }

    fn build(&self)->Result<String,Box<dyn Error>>{
        let file = fs::read_to_string(&self.file_path)?;

        println!("With text:\n {file}");

        Ok(file.trim().to_string())
    }
}

fn search<'a>(query:&str,content: &'a str)->Vec<&'a str>{
    content
        .lines() 
        .filter(|lines| lines.contains(query))
        .collect()
}

fn main()->Result<(),Box<dyn Error>> {
    let args : Vec<String> = env::args().collect();
    // this is for the argument
    let config = Config::new(&args)?; 
    
    //to read the file
    let file = Config::build(&config)?; 
    

    let _ =format!("The query is {} in {}",config.query,config.file_path);

   let result =  search(&config.query,&file);

   for line in result{
       println!("Lines: {}",line);
   }
    Ok(())
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn one_result(){
        let query = "rust";
        let content = "\
            Welcome to the channel where
            I code on rust
            safe,fase,productive.
        ";

        assert_eq!(vec!["rust"],search(query,content));
    }
}
