use std::collections::HashMap;

use crate::{
    request::{Assertion, ResponseCapture},
    schema::SchemaRegistry,
};

use super::{
    Rule,
    request_error,
};

pub(in crate::parser) fn parse_response_captures(
    response_capture_raw: Vec<(String, pest::Span<'_>)>,
    scalar_map: &HashMap<String, String>,
) -> Result<Vec<ResponseCapture>, pest::error::Error<Rule>> {
    let mut response_captures = Vec::new();

    for (raw, span) in response_capture_raw {
        let capture = ResponseCapture::parse(raw.as_str(), scalar_map).map_err(|error| {
            request_error(error.0.as_str(), span)
        })?;
        response_captures.push(capture);
    }

    Ok(response_captures)
}

pub(in crate::parser) fn parse_assertions(
    assertion_raw: Vec<(String, pest::Span<'_>)>,
    scalar_map: &HashMap<String, String>,
    schema_registry: &SchemaRegistry,
) -> Result<Vec<Assertion>, pest::error::Error<Rule>> {
    let mut assertions = Vec::new();

    for (raw, span) in assertion_raw {
        let assertion = Assertion::parse_with_registry(raw.as_str(), scalar_map, schema_registry)
            .map_err(|error| request_error(error.0.as_str(), span))?;
        assertions.push(assertion);
    }

    Ok(assertions)
}

pub(in crate::parser) fn validate_fragment_guards(
    fragment_guard_raw: Vec<(String, pest::Span<'_>)>,
    scalar_map: &HashMap<String, String>,
    schema_registry: &SchemaRegistry,
) -> Result<(), pest::error::Error<Rule>> {
    for (guard, span) in fragment_guard_raw {
        let wrapped = format!("^ {}", guard);
        Assertion::parse_with_registry(wrapped.as_str(), scalar_map, schema_registry)
            .map_err(|error| request_error(error.0.as_str(), span))?;
    }

    Ok(())
}