use crate::creds::Credentials;
use crate::error::Error;
use crate::protocol::query;
use crate::region::Region;
use crate::xml;

const SERVICE: &str = "cloudformation";
const VERSION: &str = "2010-05-15";

#[derive(Debug, Clone)]
pub struct StackOutput {
    pub key: String,
    pub value: String,
}

pub fn describe_stacks(
    creds: &Credentials,
    region: &Region,
    stack_name: &str,
) -> Result<Vec<StackOutput>, Error> {
    let xml_body = query::call(
        creds,
        region,
        SERVICE,
        "DescribeStacks",
        VERSION,
        &[("StackName", stack_name.to_string())],
    )?;
    parse_describe_stacks(&xml_body, stack_name)
}

fn parse_describe_stacks(xml_body: &str, stack_name: &str) -> Result<Vec<StackOutput>, Error> {
    let stacks = xml::inner(xml_body, "Stacks").unwrap_or("");
    let first = xml::inner(stacks, "member")
        .ok_or_else(|| Error::parse(format!("stack `{stack_name}` not found in response")))?;
    let outputs_block = xml::inner(first, "Outputs").unwrap_or("");

    let mut outputs = Vec::new();
    for member in xml::inners(outputs_block, "member") {
        outputs.push(StackOutput {
            key: xml::unescape(xml::inner(member, "OutputKey").unwrap_or("")),
            value: xml::unescape(xml::inner(member, "OutputValue").unwrap_or("")),
        });
    }
    Ok(outputs)
}
