use reqwest::header;
use reqwest::{Client, RequestBuilder};
use std::error::Error;
use std::time::Duration;

use constant;
use term;

pub fn test(url: &String) -> Result<Option<String>, Box<Error>> {
    let address: Vec<&str> = vec!["CoordinatorPortType", "CoordinatorPortType11"];
    let test_body: Vec<&str> = vec![constant::EXEC_BODY, constant::SIMPLE_BODY];
    let term = term::TERM.clone();
    let client = Client::builder()
        .danger_disable_hostname_verification()
        .timeout(Some(Duration::from_secs(10)))
        .build()?;
    for (addr, body) in iproduct!(address, test_body) {
        let url = format!("{}/wls-wsat/{}", url, addr);
        let mut request = client.post(&url);
        request
            .header(header::UserAgent::new(constant::USER_AGENT))
            .header(header::ContentType::xml())
            .body(body);
        match try_request(&mut request) {
            Ok(true) => return Ok(Some(url)),
            Ok(false) => continue,
            Err(e) => term.cout(format!("EE! {}\n", e), &term::ERR_SPEC),
        }
    }
    Ok(None)
}

fn try_request(request: &mut RequestBuilder) -> Result<bool, Box<Error>> {
    let mut response = request.send()?;
    let response = if !response.status().is_success() {
        return Ok(false);
    } else {
        response.text()?
    };
    if response.starts_with(constant::VULNER_TEXT) {
        Ok(true)
    } else {
        Ok(false)
    }
}
