//! Trust registry module for issuer validation.
//!
//! Validates issuers against the `LastID` trust registry to ensure credentials
//! are issued by authorized entities.

mod cache;
mod client;
mod types;

use async_trait::async_trait;
pub use cache::TrustRegistryCache;
pub use client::TrustRegistryClient;
pub use types::{ES256PublicKey, IssuerInfo, IssuerStatus};

use crate::error::TrustRegistryError;

/// Trust registry interface.
///
/// Validates issuers against the `LastID` trust registry to ensure credentials
/// are issued by authorized entities.
///
/// # Platform Differences
///
/// - **Native**: Requires `Send + Sync` for use across threads
/// - **WASM**: No thread safety requirements (single-threaded)
#[cfg(not(target_arch = "wasm32"))]
#[async_trait]
pub trait TrustRegistry: Send + Sync {
    /// Get issuer information by DID.
    async fn get_issuer(&self, did: &str) -> Result<IssuerInfo, TrustRegistryError>;

    /// Validate an issuer is authorized.
    async fn validate_issuer(&self, did: &str) -> Result<IssuerInfo, TrustRegistryError> {
        let issuer = self.get_issuer(did).await?;
        if issuer.status.is_valid() {
            Ok(issuer)
        } else {
            Err(TrustRegistryError::invalid_status(issuer.status))
        }
    }

    /// Invalidate a cached issuer entry.
    async fn invalidate_cache(&self, did: &str);
}

/// Trust registry interface (WASM version).
///
/// Validates issuers against the `LastID` trust registry to ensure credentials
/// are issued by authorized entities.
#[cfg(target_arch = "wasm32")]
#[async_trait(?Send)]
pub trait TrustRegistry {
    /// Get issuer information by DID.
    ///
    /// # Arguments
    ///
    /// * `did` - Enterprise DID (e.g., "did:lastid:acmecorp.com")
    ///
    /// # Returns
    ///
    /// * `IssuerInfo` - Issuer metadata including status and permitted types
    ///
    /// # Errors
    ///
    /// * `TrustRegistryError::IssuerNotFound` - DID not registered
    /// * `TrustRegistryError::Http` - Network or server error
    async fn get_issuer(&self, did: &str) -> Result<IssuerInfo, TrustRegistryError>;

    /// Validate an issuer is authorized.
    ///
    /// Convenience method that checks `issuer.status.is_valid()` after
    /// fetching.
    ///
    /// # Returns
    ///
    /// * `Ok(IssuerInfo)` - Issuer is valid (status: registered or authorized)
    /// * `Err(InvalidIssuerStatus)` - Issuer is suspended or revoked
    async fn validate_issuer(&self, did: &str) -> Result<IssuerInfo, TrustRegistryError> {
        let issuer = self.get_issuer(did).await?;

        if !issuer.status.is_valid() {
            return Err(TrustRegistryError::InvalidIssuerStatus {
                status: issuer.status,
            });
        }

        Ok(issuer)
    }

    /// Invalidate cached issuer (if caching is enabled).
    async fn invalidate_cache(&self, did: &str);
}
