use bucketwarden_auth::{AccessKey, AuthError, AuthStore, CredentialRecord};

#[test]
fn access_key_rotation_revokes_old_key_and_creates_replacement() {
    let mut store = AuthStore::new();
    store.create_local_user("alice");
    store
        .put_access_key(AccessKey::active("alice", "AKIAOLD", "old-secret"))
        .expect("old");

    let rotation = store
        .rotate_access_key("AKIAOLD", "AKIANEW", "new-secret", 42)
        .expect("rotation");

    assert_eq!(rotation.old_access_key_id, "AKIAOLD");
    assert_eq!(rotation.new_access_key_id, "AKIANEW");
    assert!(matches!(
        store.resolve_credential("AKIAOLD", 42),
        Err(AuthError::DisabledAccessKey(_) | AuthError::RevokedCredential(_))
    ));
    assert!(matches!(
        store.credential("AKIANEW"),
        Some(CredentialRecord::AccessKey(key))
            if key.previous_access_key_id.as_deref() == Some("AKIAOLD")
                && key.rotated_at_epoch_seconds == Some(42)
    ));
    assert_eq!(
        store
            .resolve_credential("AKIANEW", 42)
            .expect("new key")
            .principal_id,
        "alice"
    );
}

#[test]
fn leaked_key_response_marks_and_revokes_access_key() {
    let mut store = AuthStore::new();
    store.create_local_user("alice");
    store
        .put_access_key(AccessKey::active("alice", "AKIALEAKED", "secret"))
        .expect("key");

    let response = store
        .report_leaked_access_key("AKIALEAKED", 99)
        .expect("leaked response");

    assert!(response.revoked);
    assert_eq!(response.principal_id, "alice");
    assert!(matches!(
        store.credential("AKIALEAKED"),
        Some(CredentialRecord::AccessKey(key))
            if key.leaked_at_epoch_seconds == Some(99)
                && key.revoked_at_epoch_seconds == Some(99)
    ));
}
