use super::*;

#[test]
fn success_with_prefixed_namespaces_yields_briefing_text() {
    let xml = r#"<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
      <SOAP-ENV:Body>
        <ns2:AreaBriefingResponse xmlns:ns2="https://lmfsweb.afss.com/Website/schemas">
          <ns2:returnStatus>true</ns2:returnStatus>
          <ns2:SimpleWeatherBriefing>METAR KIAD 041952Z 28008KT 10SM FEW250 29/13 A3003&#xA;TAF KIAD 041730Z ...</ns2:SimpleWeatherBriefing>
        </ns2:AreaBriefingResponse>
      </SOAP-ENV:Body>
    </SOAP-ENV:Envelope>"#;
    let outcome = parse_area_briefing(xml).expect("parses");
    match outcome {
        Outcome::Success {
            simple_briefing: Some(text),
        } => {
            assert!(text.starts_with("METAR KIAD 041952Z"));
            assert!(
                text.contains("\nTAF KIAD"),
                "entity-encoded newline survives"
            );
        }
        other => panic!("expected success with briefing, got {other:?}"),
    }
}

#[test]
fn failure_collects_coded_messages() {
    let xml = r#"<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <AreaBriefingResponse xmlns="https://lmfsweb.afss.com/Website/schemas">
          <returnStatus>false</returnStatus>
          <returnCodedMessage><code>AUTH001</code><message>Vendor not authorized</message></returnCodedMessage>
          <returnCodedMessage><code>VAL002</code><message>briefingRadius out of range</message></returnCodedMessage>
        </AreaBriefingResponse>
      </soap:Body>
    </soap:Envelope>"#;
    let outcome = parse_area_briefing(xml).expect("parses");
    assert_eq!(
        outcome,
        Outcome::Failure {
            messages: vec![
                "AUTH001: Vendor not authorized".to_owned(),
                "VAL002: briefingRadius out of range".to_owned(),
            ],
        }
    );
}

#[test]
fn failure_collects_legacy_return_messages() {
    let xml = r#"<Envelope><Body><AreaBriefingResponse>
      <returnStatus>false</returnStatus>
      <returnMessage>Invalid fix name</returnMessage>
    </AreaBriefingResponse></Body></Envelope>"#;
    let outcome = parse_area_briefing(xml).expect("parses");
    assert_eq!(
        outcome,
        Outcome::Failure {
            messages: vec!["Invalid fix name".to_owned()]
        }
    );
}

#[test]
fn pretty_printed_error_elements_are_trimmed() {
    // A pretty-printing server pads code/message/faultstring with
    // indentation; the surfaced strings must be exact, not padded.
    let xml = "<Envelope><Body><AreaBriefingResponse>\n\
        <returnStatus>\n  false\n  </returnStatus>\n\
        <returnCodedMessage>\n\
          <code>\n    AUTH001\n  </code>\n\
          <message>\n    Vendor not authorized\n  </message>\n\
        </returnCodedMessage>\n\
        <returnMessage>\n  legacy text\n</returnMessage>\n\
    </AreaBriefingResponse></Body></Envelope>";
    let outcome = parse_area_briefing(xml).expect("parses");
    assert_eq!(
        outcome,
        Outcome::Failure {
            messages: vec![
                "AUTH001: Vendor not authorized".to_owned(),
                "legacy text".to_owned(),
            ],
        }
    );
}

#[test]
fn soap_fault_is_reported_as_fault() {
    let xml = r#"<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
      <soap:Body>
        <soap:Fault>
          <faultcode>soap:Client</faultcode>
          <faultstring>Unmarshalling Error: unexpected element</faultstring>
        </soap:Fault>
      </soap:Body>
    </soap:Envelope>"#;
    let outcome = parse_area_briefing(xml).expect("parses");
    assert_eq!(
        outcome,
        Outcome::Fault {
            message: "Unmarshalling Error: unexpected element".to_owned()
        }
    );
}

#[test]
fn missing_return_status_is_an_error() {
    let xml = "<Envelope><Body><SomethingElse/></Body></Envelope>";
    assert!(matches!(
        parse_area_briefing(xml),
        Err(ParseError::MissingReturnStatus)
    ));
}

#[test]
fn unrecognized_return_status_is_an_error() {
    let xml = "<AreaBriefingResponse><returnStatus>maybe</returnStatus></AreaBriefingResponse>";
    assert!(matches!(
        parse_area_briefing(xml),
        Err(ParseError::BadReturnStatus { .. })
    ));
}
