//! Predicate Index Keys (Federated Policy) — global predicate-based queries.

use super::builders::global_key;

/// Predicate index key: `\x00PRED:{predicate}:{hash_hex}`
///
/// Global index for querying assertions by predicate alone.
/// Used by Aphoria to find all "acknowledged" assertions for policy export.
pub fn predicate_index_key(predicate: &str, hash_hex: &str) -> Vec<u8> {
    let suffix = format!("{}:{}", predicate, hash_hex);
    global_key(b"PRED:", suffix.as_bytes())
}

/// Predicate index scan prefix: `\x00PRED:{predicate}:`
///
/// Scan all assertion hashes for a given predicate.
pub fn predicate_scan_prefix(predicate: &str) -> Vec<u8> {
    let suffix = format!("{}:", predicate);
    global_key(b"PRED:", suffix.as_bytes())
}

/// Extract hash from a predicate index key: `\x00PRED:{predicate}:{hash_hex}`
///
/// Returns the hash_hex portion.
pub fn extract_predicate_index_hash(key: &[u8]) -> Option<String> {
    let prefix = b"\x00PRED:";
    if !key.starts_with(prefix) {
        return None;
    }
    let after_prefix = &key[prefix.len()..];
    // Format is {predicate}:{hash_hex}
    // Find the last colon (hash is always 64 hex chars)
    let key_str = std::str::from_utf8(after_prefix).ok()?;
    let last_colon = key_str.rfind(':')?;
    let hash_part = &key_str[last_colon + 1..];
    if hash_part.len() == 64 && hash_part.chars().all(|c| c.is_ascii_hexdigit()) {
        Some(hash_part.to_string())
    } else {
        None
    }
}
