use rpki::data_model::rc::{
    Afi, AsIdentifierChoice, AsResourceSet, IpAddressChoice, IpAddressFamily, IpResourceSet,
    ResourceCertKind,
};
use rpki::data_model::ta::{TaCertificate, TaCertificateProfileError};

fn apnic_ta() -> TaCertificate {
    let der = std::fs::read("tests/fixtures/ta/apnic-ta.cer").expect("read apnic ta");
    TaCertificate::decode_der(&der).expect("decode apnic ta")
}

#[test]
fn ta_rc_constraints_reject_wrong_kind() {
    let ta = apnic_ta();
    let mut rc = ta.rc_ca.clone();
    rc.kind = ResourceCertKind::Ee;
    assert!(matches!(
        TaCertificate::validate_rc_constraints(&rc),
        Err(TaCertificateProfileError::NotCa)
    ));
}

#[test]
fn ta_rc_constraints_reject_missing_policies_oid() {
    let ta = apnic_ta();
    let mut rc = ta.rc_ca.clone();
    rc.tbs.extensions.certificate_policies_oid = None;
    assert!(matches!(
        TaCertificate::validate_rc_constraints(&rc),
        Err(TaCertificateProfileError::MissingOrInvalidCertificatePolicies)
    ));
}

#[test]
fn ta_rc_constraints_reject_missing_subject_key_identifier() {
    let ta = apnic_ta();
    let mut rc = ta.rc_ca.clone();
    rc.tbs.extensions.subject_key_identifier = None;
    assert!(matches!(
        TaCertificate::validate_rc_constraints(&rc),
        Err(TaCertificateProfileError::MissingSubjectKeyIdentifier)
    ));
}

#[test]
fn ta_rc_constraints_reject_missing_resources() {
    let ta = apnic_ta();
    let mut rc = ta.rc_ca.clone();
    rc.tbs.extensions.ip_resources = None;
    rc.tbs.extensions.as_resources = None;
    assert!(matches!(
        TaCertificate::validate_rc_constraints(&rc),
        Err(TaCertificateProfileError::ResourcesMissing)
    ));
}

#[test]
fn ta_rc_constraints_reject_empty_resources() {
    let ta = apnic_ta();
    let mut rc = ta.rc_ca.clone();
    rc.tbs.extensions.ip_resources = Some(IpResourceSet {
        families: vec![IpAddressFamily {
            afi: Afi::Ipv4,
            choice: IpAddressChoice::AddressesOrRanges(vec![]),
        }],
    });
    rc.tbs.extensions.as_resources = None;
    assert!(matches!(
        TaCertificate::validate_rc_constraints(&rc),
        Err(TaCertificateProfileError::ResourcesEmpty)
    ));
}

#[test]
fn ta_rc_constraints_reject_ip_inherit() {
    let ta = apnic_ta();
    let mut rc = ta.rc_ca.clone();
    rc.tbs.extensions.ip_resources = Some(IpResourceSet {
        families: vec![IpAddressFamily {
            afi: Afi::Ipv6,
            choice: IpAddressChoice::Inherit,
        }],
    });
    assert!(matches!(
        TaCertificate::validate_rc_constraints(&rc),
        Err(TaCertificateProfileError::IpResourcesInherit)
    ));
}

#[test]
fn ta_rc_constraints_reject_as_inherit() {
    let ta = apnic_ta();
    let mut rc = ta.rc_ca.clone();
    rc.tbs.extensions.as_resources = Some(AsResourceSet {
        asnum: Some(AsIdentifierChoice::Inherit),
        rdi: None,
    });
    assert!(matches!(
        TaCertificate::validate_rc_constraints(&rc),
        Err(TaCertificateProfileError::AsResourcesInherit)
    ));
}
