use rpki::data_model::rc::{
    Afi, AsIdOrRange, AsIdentifierChoice, AsResourceSet, IpAddressChoice, IpAddressFamily,
    IpAddressOrRange, IpPrefix,
};

#[test]
fn ip_address_family_contains_prefix_afi_mismatch_is_false() {
    let fam = IpAddressFamily {
        afi: Afi::Ipv4,
        choice: IpAddressChoice::Inherit,
    };
    let p = IpPrefix {
        afi: Afi::Ipv6,
        prefix_len: 0,
        addr: vec![0; 16],
    };
    assert!(!fam.contains_prefix(&p));
}

#[test]
fn ip_address_family_inherit_covers_all_prefixes_of_same_afi() {
    let fam = IpAddressFamily {
        afi: Afi::Ipv6,
        choice: IpAddressChoice::Inherit,
    };
    let p = IpPrefix {
        afi: Afi::Ipv6,
        prefix_len: 32,
        addr: vec![0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
    };
    assert!(fam.contains_prefix(&p));
}

#[test]
fn as_resource_set_asnum_single_id_returns_expected_values() {
    let inherit = AsResourceSet {
        asnum: Some(AsIdentifierChoice::Inherit),
        rdi: None,
    };
    assert_eq!(inherit.asnum_single_id(), None);

    let single_id = AsResourceSet {
        asnum: Some(AsIdentifierChoice::AsIdsOrRanges(vec![AsIdOrRange::Id(
            64512,
        )])),
        rdi: None,
    };
    assert_eq!(single_id.asnum_single_id(), Some(64512));

    let single_range = AsResourceSet {
        asnum: None,
        rdi: Some(AsIdentifierChoice::AsIdsOrRanges(vec![
            AsIdOrRange::Range {
                min: 64512,
                max: 64520,
            },
        ])),
    };
    assert_eq!(single_range.asnum_single_id(), None);

    let multiple = AsResourceSet {
        asnum: Some(AsIdentifierChoice::AsIdsOrRanges(vec![
            AsIdOrRange::Id(64512),
            AsIdOrRange::Id(64513),
        ])),
        rdi: None,
    };
    assert_eq!(multiple.asnum_single_id(), None);
}

#[test]
fn as_identifier_choice_has_range_detects_ranges() {
    assert!(!AsIdentifierChoice::Inherit.has_range());
    assert!(!AsIdentifierChoice::AsIdsOrRanges(vec![AsIdOrRange::Id(64512)]).has_range());
    assert!(
        AsIdentifierChoice::AsIdsOrRanges(vec![AsIdOrRange::Range { min: 1, max: 2 }]).has_range()
    );
}

#[test]
fn ip_resource_contains_prefix_finds_matching_family() {
    let fam_v6 = IpAddressFamily {
        afi: Afi::Ipv6,
        choice: IpAddressChoice::AddressesOrRanges(vec![IpAddressOrRange::Prefix(IpPrefix {
            afi: Afi::Ipv6,
            prefix_len: 32,
            addr: vec![0x20, 0x01, 0x0d, 0xb8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        })]),
    };
    let set = rpki::data_model::rc::IpResourceSet {
        families: vec![fam_v6],
    };

    let p = IpPrefix {
        afi: Afi::Ipv6,
        prefix_len: 48,
        addr: vec![
            0x20, 0x01, 0x0d, 0xb8, 0x12, 0x34, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        ],
    };
    assert!(set.contains_prefix(&p));
}
