//! KMS Module Facade
//!
//! Provides a stable, trait-based interface for the KMS module,
//! reducing coupling by hiding implementation details.

use async_trait::async_trait;

use crate::kms::error::{KmsError, Result};
use crate::kms::types::{KeyData, KeyType, ProviderCredentials};

/// Stable facade trait for Key Management Service operations
///
/// This trait defines the public contract for KMS operations,
/// allowing implementations to change without affecting consumers.
///
/// # Design Goals
///
/// - **Stable Interface**: Public API remains constant across refactorings
/// - **Implementation Hiding**: Internal details are not exposed
/// - **Testability**: Easy to mock for testing
/// - **Extensibility**: New features added without breaking changes
///
/// # Usage
///
/// ```rust,no_run
/// use control_center::kms::{KmsService, KeyType};
/// use std::sync::Arc;
///
/// async fn example(kms: Arc<dyn KmsService>) -> anyhow::Result<()> {
///     // Use the trait, not the concrete type
///     let key = kms.generate_key(KeyType::Asymmetric).await?;
///     println!("Generated key: {}", key.key_id);
///     Ok(())
/// }
/// ```
#[async_trait]
pub trait KmsService: Send + Sync {
    /// Initialize the KMS system
    ///
    /// Performs one-time setup including backend initialization,
    /// rotation scheduler startup, and credential manager configuration.
    ///
    /// # Errors
    ///
    /// - `Configuration` - Invalid configuration
    /// - `Backend` - Backend initialization failed
    /// - `Internal` - System initialization failed
    async fn initialize(&mut self) -> Result<()>;

    /// Get a key by ID
    ///
    /// Retrieves key data from the configured backend.
    /// Access is logged for audit purposes.
    ///
    /// # Arguments
    ///
    /// * `key_id` - Unique identifier for the key
    ///
    /// # Returns
    ///
    /// Key data if found, None otherwise
    ///
    /// # Errors
    ///
    /// - `Backend` - Backend query failed
    /// - `Audit` - Audit logging failed
    async fn get_key(&self, key_id: &str) -> Result<Option<KeyData>>;

    /// Store a new key
    ///
    /// Persists key data to the configured backend.
    /// Storage operation is logged for audit purposes.
    ///
    /// # Arguments
    ///
    /// * `key` - Key data to store
    ///
    /// # Returns
    ///
    /// The stored key ID
    ///
    /// # Errors
    ///
    /// - `KeyAlreadyExists` - Key with same ID already exists
    /// - `Validation` - Invalid key data
    /// - `Backend` - Backend storage failed
    async fn store_key(&self, key: KeyData) -> Result<String>;

    /// Delete a key by ID
    ///
    /// Removes key from the backend. Deletion is permanent.
    /// Operation is logged for audit purposes.
    ///
    /// # Arguments
    ///
    /// * `key_id` - Unique identifier for the key
    ///
    /// # Returns
    ///
    /// true if key was deleted, false if not found
    ///
    /// # Errors
    ///
    /// - `Backend` - Backend deletion failed
    /// - `Audit` - Audit logging failed
    async fn delete_key(&self, key_id: &str) -> Result<bool>;

    /// Encrypt data with a key
    ///
    /// Uses the specified key to encrypt plaintext data.
    ///
    /// # Arguments
    ///
    /// * `key_id` - Key to use for encryption
    /// * `plaintext` - Data to encrypt
    ///
    /// # Returns
    ///
    /// Encrypted ciphertext
    ///
    /// # Errors
    ///
    /// - `KeyNotFound` - Specified key does not exist
    /// - `Cryptographic` - Encryption operation failed
    /// - `PermissionDenied` - Key does not allow encryption
    async fn encrypt(&self, key_id: &str, plaintext: &[u8]) -> Result<Vec<u8>>;

    /// Decrypt data with a key
    ///
    /// Uses the specified key to decrypt ciphertext data.
    ///
    /// # Arguments
    ///
    /// * `key_id` - Key to use for decryption
    /// * `ciphertext` - Data to decrypt
    ///
    /// # Returns
    ///
    /// Decrypted plaintext
    ///
    /// # Errors
    ///
    /// - `KeyNotFound` - Specified key does not exist
    /// - `Cryptographic` - Decryption operation failed
    /// - `PermissionDenied` - Key does not allow decryption
    async fn decrypt(&self, key_id: &str, ciphertext: &[u8]) -> Result<Vec<u8>>;

    /// Generate a new encryption key
    ///
    /// Creates a new key with the specified parameters and stores it.
    ///
    /// # Arguments
    ///
    /// * `key_type` - Type of key to generate
    ///
    /// # Returns
    ///
    /// Generated key data
    ///
    /// # Errors
    ///
    /// - `Cryptographic` - Key generation failed
    /// - `Backend` - Storage failed
    async fn generate_key(&self, key_type: KeyType) -> Result<KeyData>;

    /// Rotate a key
    ///
    /// Generates a new version of an existing key.
    /// Old version is marked as deprecated but retained.
    ///
    /// # Arguments
    ///
    /// * `key_id` - Key to rotate
    ///
    /// # Returns
    ///
    /// New key data
    ///
    /// # Errors
    ///
    /// - `KeyNotFound` - Specified key does not exist
    /// - `Rotation` - Rotation operation failed
    async fn rotate_key(&self, key_id: &str) -> Result<KeyData>;

    /// Get provider credentials
    ///
    /// Retrieves stored credentials for a cloud provider.
    ///
    /// # Arguments
    ///
    /// * `provider` - Provider name (e.g., "aws", "upcloud")
    ///
    /// # Returns
    ///
    /// Provider credentials if found
    ///
    /// # Errors
    ///
    /// - `Backend` - Credential retrieval failed
    async fn get_provider_credentials(&self, provider: &str)
        -> Result<Option<ProviderCredentials>>;

    /// Store provider credentials
    ///
    /// Securely stores credentials for a cloud provider.
    ///
    /// # Arguments
    ///
    /// * `provider` - Provider name
    /// * `credentials` - Provider credentials
    ///
    /// # Errors
    ///
    /// - `Backend` - Credential storage failed
    /// - `Cryptographic` - Credential encryption failed
    async fn store_provider_credentials(
        &self,
        provider: &str,
        credentials: ProviderCredentials,
    ) -> Result<()>;

    /// Shutdown the KMS system
    ///
    /// Gracefully shuts down all KMS components including
    /// rotation scheduler and backend connections.
    ///
    /// # Errors
    ///
    /// - `Backend` - Backend shutdown failed
    async fn shutdown(&mut self) -> Result<()>;
}

/// Extension trait for advanced KMS operations
///
/// Provides optional advanced functionality that not all implementations
/// may support. Check backend capabilities before using.
#[async_trait]
pub trait KmsServiceExt: KmsService {
    /// Health check for KMS system
    ///
    /// Returns detailed health status for all components.
    async fn health_check(&self) -> Result<KmsHealthStatus>;

    /// List all keys matching criteria
    ///
    /// Returns keys filtered by optional parameters.
    ///
    /// # Arguments
    ///
    /// * `key_type` - Filter by key type (None for all)
    /// * `status` - Filter by status (None for all)
    ///
    /// # Returns
    ///
    /// Vector of matching key IDs
    async fn list_keys(
        &self,
        key_type: Option<KeyType>,
        status: Option<KeyStatus>,
    ) -> Result<Vec<String>>;

    /// Get key statistics
    ///
    /// Returns aggregate metrics about keys in the system.
    async fn get_statistics(&self) -> Result<KmsStatistics>;

    /// Export key for backup
    ///
    /// Exports a key in encrypted form for backup purposes.
    /// Requires export permission on the key.
    ///
    /// # Arguments
    ///
    /// * `key_id` - Key to export
    /// * `wrap_key_id` - Key to use for wrapping
    ///
    /// # Returns
    ///
    /// Wrapped key data
    async fn export_key(&self, key_id: &str, wrap_key_id: &str) -> Result<Vec<u8>>;

    /// Import a key from backup
    ///
    /// Imports a previously exported key.
    ///
    /// # Arguments
    ///
    /// * `wrapped_key` - Encrypted key data
    /// * `unwrap_key_id` - Key to use for unwrapping
    ///
    /// # Returns
    ///
    /// Imported key ID
    async fn import_key(&self, wrapped_key: &[u8], unwrap_key_id: &str) -> Result<String>;
}

/// KMS health status
#[derive(Debug, Clone)]
pub struct KmsHealthStatus {
    pub backend: ComponentHealth,
    pub rotation: ComponentHealth,
    pub credentials: ComponentHealth,
    pub overall: bool,
}

impl KmsHealthStatus {
    pub fn is_healthy(&self) -> bool {
        self.overall
    }
}

/// Component health status
#[derive(Debug, Clone)]
pub struct ComponentHealth {
    pub healthy: bool,
    pub message: Option<String>,
}

impl ComponentHealth {
    pub fn is_healthy(&self) -> bool {
        self.healthy
    }
}

/// Key status enumeration (re-exported for facade)
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum KeyStatus {
    Active,
    Pending,
    Deactivated,
    Compromised,
    Destroyed,
    Archived,
}

/// KMS statistics
#[derive(Debug, Clone)]
pub struct KmsStatistics {
    pub total_keys: usize,
    pub active_keys: usize,
    pub expired_keys: usize,
    pub rotation_pending: usize,
}
