use crate::{config::TestConfiguration, error::RatError, factory, store::VariableStore};
use std::ops::Deref;

pub struct Rat;

impl Rat {
    pub fn new() -> Self {
        Self {}
    }

    pub fn test(
        self,
        global: Vec<VariableStore>,
        tests: Vec<TestConfiguration>,
    ) -> Result<(), RatError> {
        let client = reqwest::blocking::Client::new();

        // some tests will output variables to be used in following tests
        let mut outputs: Vec<VariableStore> = Vec::new();

        for (test, endpoint, multi_step) in tests.into_iter() {
            let mut store_composed = vec![global.as_slice(), outputs.as_slice()];

            let endpoint = factory::endpoint(&store_composed, &test, &endpoint);
            let response = client.execute(endpoint.build())?;

            let response = factory::reponse(response)?;
            if test.verbose == Some(true) {
                log::debug!("{:#?}", response);
            }
            store_composed.push(response.deref());

            //println!("{:#?}", &store_composed);

            let result = test.assert(&store_composed);

            result.print();

            let new_outputs = factory::outputs(&store_composed, multi_step.outputs)?;
            outputs.push(new_outputs);
        }
        Ok(())
    }
}