//! Validation utilities for source registry operations.

use crate::error::{ApiError, Result};

/// Validate and decode a hex hash string into a 32-byte array.
///
/// # Errors
///
/// Returns an error if:
/// - The hash is not valid hex
/// - The hash is not exactly 64 hex characters (32 bytes)
pub fn validate_hash(hash: &str) -> Result<[u8; 32]> {
    let hash_bytes = hex::decode(hash)
        .map_err(|e| ApiError::InvalidRequest(format!("Invalid hash hex: {}", e)))?;

    if hash_bytes.len() != 32 {
        return Err(ApiError::InvalidHashLength { expected: 32, actual: hash_bytes.len() });
    }

    let mut hash_arr = [0u8; 32];
    hash_arr.copy_from_slice(&hash_bytes);
    Ok(hash_arr)
}

/// Validate tier is within valid range (0-5).
///
/// # Errors
///
/// Returns an error if tier is greater than 5.
pub fn validate_tier(tier: u8) -> Result<()> {
    if tier > 5 {
        return Err(ApiError::InvalidRequest("Tier must be 0-5".to_string()));
    }
    Ok(())
}

/// Get current UNIX timestamp in seconds.
pub fn current_timestamp() -> u64 {
    std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .map(|d| d.as_secs())
        .unwrap_or(0)
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_validate_hash_success() {
        let hash = "a".repeat(64);
        let result = validate_hash(&hash);
        assert!(result.is_ok());
        let arr = result.unwrap();
        assert_eq!(arr.len(), 32);
    }

    #[test]
    fn test_validate_hash_invalid_hex() {
        let hash = "g".repeat(64);
        let result = validate_hash(&hash);
        assert!(result.is_err());
    }

    #[test]
    fn test_validate_hash_wrong_length() {
        let hash = "ab".repeat(20); // 40 chars = 20 bytes
        let result = validate_hash(&hash);
        assert!(result.is_err());
    }

    #[test]
    fn test_validate_tier_success() {
        assert!(validate_tier(0).is_ok());
        assert!(validate_tier(3).is_ok());
        assert!(validate_tier(5).is_ok());
    }

    #[test]
    fn test_validate_tier_failure() {
        assert!(validate_tier(6).is_err());
        assert!(validate_tier(10).is_err());
    }

    #[test]
    fn test_current_timestamp() {
        let ts = current_timestamp();
        assert!(ts > 1_600_000_000); // After 2020
        assert!(ts < 2_000_000_000); // Before 2033
    }
}
