// SPDX-FileCopyrightText: Heiko Schaefer <heiko@schaefer.name>
// SPDX-License-Identifier: MIT OR Apache-2.0

#![allow(clippy::expect_used)]

use std::time::SystemTime;

use chrono::DateTime;
use rpgpie::certificate::{Certificate, Checked};

fn load_cert(filename: &str) -> Checked {
    let mut read = std::fs::File::open(filename).expect("open");
    let c = Certificate::load(&mut read).expect("load");

    assert_eq!(c.len(), 1);

    Checked::from(c.into_iter().next().expect("asserted"))
}

#[test]
fn test_validity_05c7775a9e8b977407fe08e69d4c5aa15426da0a() {
    let _ = env_logger::builder().try_init();

    let checked = load_cert("tests/validity/05c7775a9e8b977407fe08e69d4c5aa15426da0a.openpgp");

    // --- validity of the primary ---

    // key is not revoked
    assert!(
        !checked.revoked_at(
            SystemTime::from(
                DateTime::parse_from_rfc3339("2025-01-01T23:59:00Z").expect("parse date")
            )
            .try_into()
            .expect("fits u32")
        )
    );

    // --- signing component keys ---

    // after the (only) binding signature was created
    let sig = checked.valid_signing_capable_component_keys_at(
        SystemTime::from(DateTime::parse_from_rfc3339("2025-05-05T00:00:00Z").expect("parse date"))
            .try_into()
            .expect("fits u32"),
    );
    assert_eq!(sig.len(), 1);

    // before the (only) binding signature was created
    let sig = checked.valid_signing_capable_component_keys_at(
        SystemTime::from(DateTime::parse_from_rfc3339("2024-09-01T00:00:00Z").expect("parse date"))
            .try_into()
            .expect("fits u32"),
    );
    assert_eq!(sig.len(), 1);
}

#[test]
fn test_validity_be2dbcf2b1e3e588ac325aeaa06b49470f8e620a() {
    let _ = env_logger::builder().try_init();

    let checked = load_cert("tests/validity/be2dbcf2b1e3e588ac325aeaa06b49470f8e620a.openpgp");

    // --- signing component keys ---

    // before the (only) binding signature was created
    let sig = checked.valid_signing_capable_component_keys_at(
        SystemTime::from(DateTime::parse_from_rfc3339("2025-05-22T01:00:00Z").expect("parse date"))
            .try_into()
            .expect("fits u32"),
    );
    assert_eq!(sig.len(), 2);
}

#[test]
fn test_validity_9d74df6f91b7bdabd5815ca84ac5588f941c2a25() {
    let _ = env_logger::builder().try_init();

    // One oddity in this cert is that the backsig was made [2022-07-09] much later than
    // key creation time [2014-11-07],
    //
    // Still, data signatures from before the binding signature should be considered valid.

    let checked = load_cert("tests/validity/9d74df6f91b7bdabd5815ca84ac5588f941c2a25.openpgp");

    // --- signing component keys ---

    // before the (only) subkey binding signature was created
    let sig = checked.valid_signing_capable_component_keys_at(
        SystemTime::from(DateTime::parse_from_rfc3339("2022-05-22T01:00:00Z").expect("parse date"))
            .try_into()
            .expect("fits u32"),
    );
    assert_eq!(sig.len(), 2);

    // after the (only) subkey binding signature was created
    let sig = checked.valid_signing_capable_component_keys_at(
        SystemTime::from(DateTime::parse_from_rfc3339("2023-01-01T01:00:00Z").expect("parse date"))
            .try_into()
            .expect("fits u32"),
    );
    assert_eq!(sig.len(), 2);
}

#[test]
fn test_validity_revoked_user_id_bob() {
    let _ = env_logger::builder().try_init();

    // This is a test certificate from sequoia-wot, it has a revoked user id, but a valid direct key
    // signature. The User Id revocation signature is the newest

    let checked = load_cert("tests/validity/userid-revoked-bob.pgp");

    // Before the User Id revocation
    assert!(
        checked
            .primary_valid_at(
                SystemTime::from(
                    DateTime::parse_from_rfc3339("2020-02-01T01:00:00Z").expect("parse date")
                )
                .try_into()
                .expect("fits u32"),
            )
            .expect("primary_valid_at")
    );

    // After the User Id revocation
    assert!(
        checked
            .primary_valid_at(
                SystemTime::from(
                    DateTime::parse_from_rfc3339("2020-04-01T01:00:00Z").expect("parse date")
                )
                .try_into()
                .expect("fits u32"),
            )
            .expect("primary_valid_at")
    );
}
