//! Key Management Service (KMS) Module
//!
//! Provides a hybrid KMS system supporting local/remote/hybrid modes with:
//! - Local SQLite backend with AES-256-GCM encryption
//! - Remote Cosmian KMS integration
//! - Intelligent caching with TTL and offline fallback
//! - Credential management for cloud providers
//! - Automatic key rotation
//! - Hardware Security Module (HSM) support
//! - Zero-knowledge proof capabilities
//! - Comprehensive audit logging
//!
//! # Architecture
//!
//! ```text
//! ┌─────────────────────────────────────────────┐
//! │          KMS Service (Facade)               │
//! ├─────────────────────────────────────────────┤
//! │                                             │
//! │  ┌──────────┐  ┌──────────┐  ┌──────────┐ │
//! │  │ Encrypt  │  │  Decrypt │  │ Generate │ │
//! │  └────┬─────┘  └────┬─────┘  └────┬─────┘ │
//! │       │             │             │        │
//! │       └─────────────┼─────────────┘        │
//! │                     ▼                       │
//! │         ┌──────────────────────┐           │
//! │         │    KMS Manager       │           │
//! │         │  - Backend routing   │           │
//! │         │  - Audit logging     │           │
//! │         │  - Rotation          │           │
//! │         └──────────┬───────────┘           │
//! │                    │                        │
//! │       ┌────────────┼────────────┐          │
//! │       ▼            ▼            ▼           │
//! │  ┌────────┐  ┌─────────┐  ┌─────────┐    │
//! │  │ Local  │  │ Remote  │  │ Hybrid  │    │
//! │  │Backend │  │ Backend │  │ Backend │    │
//! │  └────────┘  └─────────┘  └─────────┘    │
//! │                                             │
//! └─────────────────────────────────────────────┘
//! ```
//!
//! # Usage - Recommended (Trait-based)
//!
//! ```rust,no_run
//! use control_center::kms::{
//!     KmsService,      // Trait for stable interface
//!     KmsManager,      // Concrete implementation
//!     KmsConfig,       // Configuration
//!     KeyType,         // Key types
//! };
//! use std::sync::Arc;
//!
//! # async fn example() -> anyhow::Result<()> {
//! let config = KmsConfig::default();
//! let mut kms: Box<dyn KmsService> = Box::new(KmsManager::new(&config).await?);
//!
//! kms.initialize().await?;
//!
//! // Use trait methods
//! let key = kms.generate_key(KeyType::Symmetric).await?;
//! let ciphertext = kms.encrypt(&key.key_id, b"secret data").await?;
//! # Ok(())
//! # }
//! ```
//!
//! # Migration Guide
//!
//! **Old code** (direct imports):
//! ```rust,ignore
//! use control_center::kms::{
//!     LocalKmsBackend, RemoteKmsBackend, AuditLogger, CacheBackend
//! };
//! ```
//!
//! **New code** (organized imports):
//! ```rust,ignore
//! use control_center::kms::{
//!     KmsService,       // Trait
//!     KmsManager,       // Implementation
//!     backends::LocalKmsBackend,  // Backend-specific
//! };
//! ```

// ============================================================================
// Module Declarations
// ============================================================================

pub mod config;
pub mod error;
pub mod facade;
pub mod interface;
pub mod types;

// Implementation modules
mod manager_impl;

// Internal implementation modules (not re-exported)
pub mod audit;
mod cache;
mod credentials;
mod hsm;
mod hybrid;
pub mod kms_service_client;
mod local;
mod remote;
mod rotation;
mod traits;
mod zkp;

// ============================================================================
// Public Exports - Stable Interface (Tier 1: Recommended)
// ============================================================================

// Factory functions and builders (primary API for new code)
// These allow decoupled creation without importing KmsManager or
// KmsServiceClient
// Core traits (stable facade)
// Re-export config types for backward compatibility
pub use config::KeySource;
// Configuration
pub use config::KmsConfig;
// Error types
pub use error::{KmsClientError, KmsError, Result};
pub use facade::{KmsService, KmsServiceExt};
pub use interface::{
    create_and_initialize_kms, create_http_kms, create_http_kms_client, create_kms,
    create_local_kms, KmsBuilder, KmsProvider,
};
// Re-export KmsBackend trait for custom implementations
pub use traits::KmsBackend;
// Essential types (used in trait methods)
pub use types::{
    AuditEvent, AuditEventType, HealthStatus, HsmInfo, HsmKeySpec, KeyAlgorithm, KeyData,
    KeyMetadata, KeyStatus, KeyType, KeyUsage, KmsMode, MigrationResult, MigrationStatus,
    MigrationVerification, ProviderCredentials, RotationState, RotationStatus, SecretBytes,
};

// KmsManager and KmsFactory are defined below in this module

// ============================================================================
// Backend Sub-Module - Advanced/Optional
// ============================================================================

/// Backend implementations and extensions
///
/// Import from this module when you need direct access to backend
/// implementations or want to implement custom backends.
///
/// # Usage
///
/// ```rust,no_run
/// use control_center::kms::backends::{
///     LocalKmsBackend,
///     RemoteKmsBackend,
///     HybridKmsBackend,
/// };
/// ```
pub mod backends {
    pub use super::hybrid::HybridKmsBackend;
    pub use super::local::LocalKmsBackend;
    pub use super::remote::RemoteKmsBackend;
}

/// Advanced traits for custom implementations
///
/// Use these traits when extending the KMS system with
/// custom components (cache, audit, rotation, etc.)
///
/// # Usage
///
/// ```rust,no_run
/// use control_center::kms::advanced::{
///     CacheBackendTrait,
///     AuditLog,
///     KeyRotation,
/// };
/// ```
pub mod advanced {
    pub use super::audit::AuditLogger;
    // Configuration types for advanced features
    pub use super::config::{
        AuditBackend, AuditConfig, AuditLogFormat, AuditLogLevel, CredentialConfig, KeySource,
        LocalConfig, RemoteConfig,
    };
    pub use super::credentials::CredentialManager;
    pub use super::rotation::RotationScheduler;
    pub use super::traits::{
        AuditLog, CacheBackend as CacheBackendTrait, CredentialStore, KeyRotation,
    };
    pub use super::types::CacheBackend;
    pub use super::types::{CacheConfig, ZkpConfig};
    // Advanced types for migration and HSM
    pub use super::types::{
        HsmInfo, HsmKeySpec, MigrationResult, MigrationStatus, MigrationVerification, RotationState,
    };
    pub use super::zkp::*;
}

// ============================================================================
// KMS Service Factory
// ============================================================================

/// KMS Service Factory
pub struct KmsFactory;

impl KmsFactory {
    /// Create a new KMS instance based on configuration
    pub async fn create_kms(config: &KmsConfig) -> Result<Box<dyn KmsBackend>> {
        match config.mode {
            KmsMode::Local => {
                let backend = local::LocalKmsBackend::new(&config.local).await?;
                Ok(Box::new(backend))
            }
            KmsMode::Remote => {
                let backend = remote::RemoteKmsBackend::new(&config.remote).await?;
                Ok(Box::new(backend))
            }
            KmsMode::Hybrid => {
                let backend = hybrid::HybridKmsBackend::new(config).await?;
                Ok(Box::new(backend))
            }
        }
    }
}

// ============================================================================
// KMS Service Manager
// ============================================================================

use audit::AuditLogger;
use credentials::CredentialManager;
use rotation::RotationScheduler;

/// KMS Service Manager
///
/// Main entry point for KMS operations. Implements the `KmsService` trait
/// and coordinates between backend, audit, rotation, and credential components.
pub struct KmsManager {
    backend: Box<dyn KmsBackend>,
    audit: AuditLogger,
    rotation_scheduler: RotationScheduler,
    credential_manager: CredentialManager,
}

impl KmsManager {
    /// Create a new KMS manager
    pub async fn new(config: &KmsConfig) -> Result<Self> {
        let backend = KmsFactory::create_kms(config).await?;
        let audit = AuditLogger::new(config.audit.clone()).await?;
        let rotation_scheduler = RotationScheduler::new(config.rotation.clone()).await?;
        let credential_manager = CredentialManager::new(config.credentials.clone()).await?;

        Ok(Self {
            backend,
            audit,
            rotation_scheduler,
            credential_manager,
        })
    }

    /// Initialize the KMS system
    pub async fn initialize(&mut self) -> Result<()> {
        // Initialize backend
        self.backend.initialize().await?;

        // Start rotation scheduler
        self.rotation_scheduler.start().await?;

        // Initialize credential manager
        self.credential_manager.initialize().await?;

        // Log initialization (best effort - don't fail on audit errors)
        let _ = self.audit.log_event(AuditEvent::system_initialized()).await;

        Ok(())
    }

    /// Get a key by ID
    pub async fn get_key(&self, key_id: &str) -> Result<Option<KeyData>> {
        let result = self.backend.get_key(key_id).await;

        // Log access attempt (best effort - don't fail on audit errors)
        let _ = match &result {
            Ok(Some(_)) => self.audit.log_event(AuditEvent::key_accessed(key_id)).await,
            Ok(None) => {
                self.audit
                    .log_event(AuditEvent::key_not_found(key_id))
                    .await
            }
            Err(e) => {
                self.audit
                    .log_event(AuditEvent::key_access_failed(key_id, e))
                    .await
            }
        };

        result
    }

    /// Store a new key
    pub async fn store_key(&self, key: KeyData) -> Result<String> {
        let result = self.backend.store_key(key.clone()).await;

        // Log storage attempt (best effort - don't fail on audit errors)
        let _ = match &result {
            Ok(key_id) => self.audit.log_event(AuditEvent::key_stored(key_id)).await,
            Err(e) => {
                self.audit
                    .log_event(AuditEvent::key_store_failed(&key.key_id, e))
                    .await
            }
        };

        result
    }

    /// Delete a key
    pub async fn delete_key(&self, key_id: &str) -> Result<bool> {
        let result = self.backend.delete_key(key_id).await;

        // Log deletion attempt (best effort - don't fail on audit errors)
        let _ = match &result {
            Ok(true) => self.audit.log_event(AuditEvent::key_deleted(key_id)).await,
            Ok(false) => {
                self.audit
                    .log_event(AuditEvent::key_delete_failed_not_found(key_id))
                    .await
            }
            Err(e) => {
                self.audit
                    .log_event(AuditEvent::key_delete_failed(key_id, e))
                    .await
            }
        };

        result
    }

    /// Get provider credentials
    pub async fn get_provider_credentials(
        &self,
        provider: &str,
    ) -> Result<Option<ProviderCredentials>> {
        self.credential_manager.get_credentials(provider).await
    }

    /// Store provider credentials
    pub async fn store_provider_credentials(
        &self,
        provider: &str,
        credentials: ProviderCredentials,
    ) -> Result<()> {
        self.credential_manager
            .store_credentials(provider, credentials)
            .await
    }

    /// Health check
    pub async fn health_check(&self) -> Result<types::KmsHealthStatus> {
        let backend_health = self.backend.health_check().await?;
        let rotation_health = self.rotation_scheduler.health_check().await?;
        let credential_health = self.credential_manager.health_check().await?;

        let overall = backend_health.is_healthy()
            && rotation_health.is_healthy()
            && credential_health.is_healthy();

        Ok(types::KmsHealthStatus {
            backend: backend_health,
            rotation: rotation_health,
            credentials: credential_health,
            overall,
        })
    }

    /// Shutdown the KMS system
    pub async fn shutdown(&mut self) -> Result<()> {
        // Stop rotation scheduler
        self.rotation_scheduler.shutdown().await?;

        // Shutdown backend
        self.backend.shutdown().await?;

        // Log shutdown (best effort - don't fail on audit errors)
        let _ = self.audit.log_event(AuditEvent::system_shutdown()).await;

        Ok(())
    }
}

// ============================================================================
// Deprecated Exports - Backward Compatibility (Remove in v2.0)
// ============================================================================

#[deprecated(
    since = "1.1.0",
    note = "Import from `kms::advanced::*` instead. Direct re-export will be removed in v2.0"
)]
pub use audit::AuditLogger as DeprecatedAuditLogger;
#[deprecated(
    since = "1.1.0",
    note = "Import from `kms::advanced::*` instead. Direct re-export will be removed in v2.0"
)]
pub use credentials::CredentialManager as DeprecatedCredentialManager;
#[deprecated(
    since = "1.1.0",
    note = "Import from `kms::backends::*` instead. Direct re-export will be removed in v2.0"
)]
pub use hybrid::HybridKmsBackend as DeprecatedHybridKmsBackend;
#[deprecated(
    since = "1.1.0",
    note = "Import from `kms::backends::*` instead. Direct re-export will be removed in v2.0"
)]
pub use local::LocalKmsBackend as DeprecatedLocalKmsBackend;
#[deprecated(
    since = "1.1.0",
    note = "Import from `kms::backends::*` instead. Direct re-export will be removed in v2.0"
)]
pub use remote::RemoteKmsBackend as DeprecatedRemoteKmsBackend;
#[deprecated(
    since = "1.1.0",
    note = "Import from `kms::advanced::*` instead. Direct re-export will be removed in v2.0"
)]
pub use rotation::RotationScheduler as DeprecatedRotationScheduler;
#[deprecated(
    since = "1.1.0",
    note = "Import from `kms::advanced::CacheBackendTrait` instead. Direct re-export will be \
            removed in v2.0"
)]
pub use traits::CacheBackend as DeprecatedCacheBackendTrait;
