//! KMS Trait Definitions
//!
//! Core traits that define the KMS backend interface and related functionality.

use std::collections::HashMap;

use async_trait::async_trait;

use crate::kms::{HealthStatus, KeyData, KmsError, ProviderCredentials};

/// Core KMS backend trait
#[async_trait]
pub trait KmsBackend: Send + Sync {
    /// Initialize the backend
    async fn initialize(&mut self) -> Result<(), KmsError>;

    /// Store a key
    async fn store_key(&self, key: KeyData) -> Result<String, KmsError>;

    /// Retrieve a key by ID
    async fn get_key(&self, key_id: &str) -> Result<Option<KeyData>, KmsError>;

    /// Update an existing key
    async fn update_key(&self, key_id: &str, key: KeyData) -> Result<(), KmsError>;

    /// Delete a key
    async fn delete_key(&self, key_id: &str) -> Result<bool, KmsError>;

    /// List all keys with optional filters
    async fn list_keys(
        &self,
        filters: Option<HashMap<String, String>>,
    ) -> Result<Vec<String>, KmsError>;

    /// Check if a key exists
    async fn key_exists(&self, key_id: &str) -> Result<bool, KmsError>;

    /// Encrypt data with a specific key
    async fn encrypt(
        &self,
        key_id: &str,
        plaintext: &[u8],
        context: Option<HashMap<String, String>>,
    ) -> Result<Vec<u8>, KmsError>;

    /// Decrypt data with a specific key
    async fn decrypt(
        &self,
        key_id: &str,
        ciphertext: &[u8],
        context: Option<HashMap<String, String>>,
    ) -> Result<Vec<u8>, KmsError>;

    /// Sign data with a specific key
    async fn sign(
        &self,
        key_id: &str,
        data: &[u8],
        algorithm: Option<String>,
    ) -> Result<Vec<u8>, KmsError>;

    /// Verify signature with a specific key
    async fn verify(
        &self,
        key_id: &str,
        data: &[u8],
        signature: &[u8],
        algorithm: Option<String>,
    ) -> Result<bool, KmsError>;

    /// Generate a data key
    async fn generate_data_key(
        &self,
        key_id: &str,
        key_spec: &str,
        context: Option<HashMap<String, String>>,
    ) -> Result<(Vec<u8>, Vec<u8>), KmsError>;

    /// Health check for the backend
    async fn health_check(&self) -> Result<HealthStatus, KmsError>;

    /// Shutdown the backend
    async fn shutdown(&mut self) -> Result<(), KmsError>;
}

/// Cache backend trait
#[async_trait]
pub trait CacheBackend: Send + Sync {
    /// Store data in cache with TTL
    async fn set(&self, key: &str, value: &[u8], ttl_seconds: u64) -> Result<(), KmsError>;

    /// Retrieve data from cache
    async fn get(&self, key: &str) -> Result<Option<Vec<u8>>, KmsError>;

    /// Delete data from cache
    async fn delete(&self, key: &str) -> Result<bool, KmsError>;

    /// Check if key exists in cache
    async fn exists(&self, key: &str) -> Result<bool, KmsError>;

    /// Set TTL for existing key
    async fn expire(&self, key: &str, ttl_seconds: u64) -> Result<bool, KmsError>;

    /// Clear all cache entries
    async fn clear(&self) -> Result<(), KmsError>;

    /// Get cache statistics
    async fn stats(&self) -> Result<HashMap<String, i64>, KmsError>;

    /// Health check for cache
    async fn health_check(&self) -> Result<HealthStatus, KmsError>;
}

/// Credential storage trait
#[async_trait]
pub trait CredentialStore: Send + Sync {
    /// Store provider credentials
    async fn store_credentials(
        &self,
        provider: &str,
        credentials: ProviderCredentials,
    ) -> Result<(), KmsError>;

    /// Retrieve provider credentials
    async fn get_credentials(
        &self,
        provider: &str,
    ) -> Result<Option<ProviderCredentials>, KmsError>;

    /// Update provider credentials
    async fn update_credentials(
        &self,
        provider: &str,
        credentials: ProviderCredentials,
    ) -> Result<(), KmsError>;

    /// Delete provider credentials
    async fn delete_credentials(&self, provider: &str) -> Result<bool, KmsError>;

    /// List all providers with stored credentials
    async fn list_providers(&self) -> Result<Vec<String>, KmsError>;

    /// Check if credentials exist for provider
    async fn credentials_exist(&self, provider: &str) -> Result<bool, KmsError>;

    /// Health check for credential store
    async fn health_check(&self) -> Result<HealthStatus, KmsError>;
}

/// Audit logging trait
#[async_trait]
pub trait AuditLog: Send + Sync {
    /// Log an audit event
    async fn log_event(&self, event: crate::kms::AuditEvent) -> Result<(), KmsError>;

    /// Query audit events with filters
    async fn query_events(
        &self,
        filters: Option<HashMap<String, String>>,
        limit: Option<usize>,
        offset: Option<usize>,
    ) -> Result<Vec<crate::kms::AuditEvent>, KmsError>;

    /// Get audit statistics
    async fn get_stats(&self) -> Result<HashMap<String, i64>, KmsError>;

    /// Archive old events
    async fn archive_events(&self, older_than_days: u32) -> Result<u64, KmsError>;

    /// Health check for audit log
    async fn health_check(&self) -> Result<HealthStatus, KmsError>;
}

/// Key rotation trait
#[async_trait]
pub trait KeyRotation: Send + Sync {
    /// Check if key needs rotation
    async fn needs_rotation(&self, key_id: &str) -> Result<bool, KmsError>;

    /// Rotate a specific key
    async fn rotate_key(&self, key_id: &str) -> Result<String, KmsError>;

    /// Schedule key rotation
    async fn schedule_rotation(&self, key_id: &str, schedule: &str) -> Result<(), KmsError>;

    /// Cancel scheduled rotation
    async fn cancel_rotation(&self, key_id: &str) -> Result<bool, KmsError>;

    /// Get rotation status for a key
    async fn rotation_status(&self, key_id: &str) -> Result<crate::kms::RotationStatus, KmsError>;

    /// List all keys scheduled for rotation
    async fn list_scheduled_rotations(&self) -> Result<Vec<String>, KmsError>;

    /// Health check for rotation system
    async fn health_check(&self) -> Result<HealthStatus, KmsError>;
}

/// Hardware Security Module trait
#[async_trait]
pub trait HsmProvider: Send + Sync {
    /// Initialize HSM connection
    async fn initialize(&mut self) -> Result<(), KmsError>;

    /// Generate key in HSM
    async fn generate_key(&self, key_spec: &crate::kms::HsmKeySpec) -> Result<String, KmsError>;

    /// Import key into HSM
    async fn import_key(
        &self,
        key_data: &[u8],
        key_spec: &crate::kms::HsmKeySpec,
    ) -> Result<String, KmsError>;

    /// Export key from HSM (if allowed)
    async fn export_key(&self, key_id: &str) -> Result<Vec<u8>, KmsError>;

    /// Delete key from HSM
    async fn delete_key(&self, key_id: &str) -> Result<bool, KmsError>;

    /// Encrypt using HSM key
    async fn encrypt(&self, key_id: &str, plaintext: &[u8]) -> Result<Vec<u8>, KmsError>;

    /// Decrypt using HSM key
    async fn decrypt(&self, key_id: &str, ciphertext: &[u8]) -> Result<Vec<u8>, KmsError>;

    /// Sign using HSM key
    async fn sign(&self, key_id: &str, data: &[u8]) -> Result<Vec<u8>, KmsError>;

    /// Verify signature using HSM key
    async fn verify(&self, key_id: &str, data: &[u8], signature: &[u8]) -> Result<bool, KmsError>;

    /// List keys in HSM
    async fn list_keys(&self) -> Result<Vec<String>, KmsError>;

    /// Get HSM information
    async fn get_info(&self) -> Result<crate::kms::HsmInfo, KmsError>;

    /// Health check for HSM
    async fn health_check(&self) -> Result<HealthStatus, KmsError>;

    /// Shutdown HSM connection
    async fn shutdown(&mut self) -> Result<(), KmsError>;
}

/// Zero-knowledge proof trait
#[async_trait]
pub trait ZkpProvider: Send + Sync {
    /// Initialize ZKP system
    async fn initialize(&mut self) -> Result<(), KmsError>;

    /// Generate proof for key access
    async fn generate_access_proof(
        &self,
        key_id: &str,
        context: &HashMap<String, String>,
    ) -> Result<Vec<u8>, KmsError>;

    /// Verify access proof
    async fn verify_access_proof(
        &self,
        proof: &[u8],
        key_id: &str,
        context: &HashMap<String, String>,
    ) -> Result<bool, KmsError>;

    /// Generate proof for key operation
    async fn generate_operation_proof(
        &self,
        operation: &str,
        key_id: &str,
        data: &[u8],
    ) -> Result<Vec<u8>, KmsError>;

    /// Verify operation proof
    async fn verify_operation_proof(
        &self,
        proof: &[u8],
        operation: &str,
        key_id: &str,
        data: &[u8],
    ) -> Result<bool, KmsError>;

    /// Get proof verification key
    async fn get_verification_key(&self) -> Result<Vec<u8>, KmsError>;

    /// Health check for ZKP system
    async fn health_check(&self) -> Result<HealthStatus, KmsError>;
}

/// Key migration trait for backend transitions
#[async_trait]
pub trait KeyMigration: Send + Sync {
    /// Migrate keys from source to destination backend
    async fn migrate_keys(
        &self,
        source: &dyn KmsBackend,
        destination: &dyn KmsBackend,
        key_ids: Option<Vec<String>>,
    ) -> Result<crate::kms::MigrationResult, KmsError>;

    /// Verify migration integrity
    async fn verify_migration(
        &self,
        source: &dyn KmsBackend,
        destination: &dyn KmsBackend,
        key_ids: &[String],
    ) -> Result<crate::kms::MigrationVerification, KmsError>;

    /// Rollback migration
    async fn rollback_migration(&self, migration_id: &str) -> Result<(), KmsError>;

    /// Get migration status
    async fn get_migration_status(
        &self,
        migration_id: &str,
    ) -> Result<crate::kms::MigrationStatus, KmsError>;
}

/// Configuration validation trait
pub trait ConfigValidation {
    /// Validate configuration
    fn validate(&self) -> Result<(), KmsError>;

    /// Get validation warnings
    fn get_warnings(&self) -> Vec<String>;

    /// Get configuration summary
    fn summary(&self) -> HashMap<String, String>;
}

/// Backend factory trait
#[async_trait]
pub trait BackendFactory: Send + Sync {
    /// Create backend instance
    async fn create(&self, config: &crate::kms::KmsConfig)
        -> Result<Box<dyn KmsBackend>, KmsError>;

    /// Get supported backend types
    fn supported_types(&self) -> Vec<String>;

    /// Validate backend configuration
    fn validate_config(&self, config: &crate::kms::KmsConfig) -> Result<(), KmsError>;
}
