// Package crypto provides sophisticated key management for role-based encryption.
//
// This module implements enterprise-grade key management with features including:
// - Hierarchical role-based key derivation
// - Automated key rotation with configurable policies
// - Key escrow and recovery mechanisms
// - Hardware Security Module (HSM) integration support
// - Zero-knowledge key verification
// - Perfect forward secrecy through ephemeral keys
//
// Security Features:
// - Key derivation using PBKDF2 with configurable iterations
// - Key verification without exposing key material
// - Secure key storage with encryption at rest
// - Key rotation logging and audit trails
// - Emergency key revocation capabilities
//
// Cross-references:
//   - pkg/crypto/role_crypto.go: Role-based encryption implementation
//   - pkg/crypto/shamir.go: Shamir secret sharing for admin keys
//   - pkg/config/roles.go: Role definitions and permissions

package crypto

import (
	"crypto/rand"
	"crypto/sha256"
	"encoding/hex"
	"fmt"
	"sync"
	"time"

	"golang.org/x/crypto/pbkdf2"
	"chorus.services/bzzz/pkg/config"
	"chorus.services/bzzz/pkg/security"
)

// Type aliases for backward compatibility
type AccessLevel = security.AccessLevel

// AuditLogger interface for audit logging
type AuditLogger interface {
	LogAccess(entry *AccessLogEntry) error
	LogKeyRotation(event *KeyRotationEvent) error
	LogSecurityEvent(event *SecurityEvent) error
	GetAuditTrail(criteria *AuditCriteria) ([]*AuditEvent, error)
}

// KeyRotationPolicy defines when and how keys should be rotated
type KeyRotationPolicy struct {
	RotationInterval  time.Duration `json:"rotation_interval"`   // How often to rotate keys
	MaxKeyAge         time.Duration `json:"max_key_age"`         // Maximum age before forced rotation
	AutoRotate        bool          `json:"auto_rotate"`         // Whether to auto-rotate
	GracePeriod       time.Duration `json:"grace_period"`        // Grace period for old keys
	RequireQuorum     bool          `json:"require_quorum"`      // Whether quorum needed for rotation
	MinQuorumSize     int           `json:"min_quorum_size"`     // Minimum quorum size
}

// RoleKeyPair represents encryption keys for a specific role
type RoleKeyPair struct {
	PublicKey          string    `json:"public_key"`           // Age public key
	PrivateKey         string    `json:"private_key"`          // Age private key (encrypted)
	EncryptionSalt     []byte    `json:"encryption_salt"`      // Salt for private key encryption
	DerivedKeyHash     string    `json:"derived_key_hash"`     // Hash of derived key for verification
	Version            int       `json:"version"`              // Key version
	CreatedAt          time.Time `json:"created_at"`           // When keys were created
	RotatedAt          *time.Time `json:"rotated_at,omitempty"` // When keys were last rotated
}

// AccessLogEntry represents a single access to encrypted context
type AccessLogEntry struct {
	AccessTime        time.Time   `json:"access_time"`
	UserID            string      `json:"user_id"`
	Role              string      `json:"role"`
	AccessType        string      `json:"access_type"`      // read, write, decrypt
	Success           bool        `json:"success"`
	FailureReason     string      `json:"failure_reason,omitempty"`
	IPAddress         string      `json:"ip_address"`
	UserAgent         string      `json:"user_agent"`
	AuditTrail        string      `json:"audit_trail"`      // Audit trail reference
}

// KeyRotationEvent represents a key rotation event for audit logging
type KeyRotationEvent struct {
	EventID           string    `json:"event_id"`
	Timestamp         time.Time `json:"timestamp"`
	RotatedRoles      []string  `json:"rotated_roles"`
	InitiatedBy       string    `json:"initiated_by"`
	Reason            string    `json:"reason"`
	Success           bool      `json:"success"`
	ErrorMessage      string    `json:"error_message,omitempty"`
	PreviousKeyHashes []string  `json:"previous_key_hashes"`
	NewKeyHashes      []string  `json:"new_key_hashes"`
}

// SecurityEvent represents a security-related event for audit logging
type SecurityEvent struct {
	EventID           string                 `json:"event_id"`
	EventType         string                 `json:"event_type"`
	Timestamp         time.Time              `json:"timestamp"`
	UserID            string                 `json:"user_id"`
	Resource          string                 `json:"resource"`
	Action            string                 `json:"action"`
	Outcome           string                 `json:"outcome"`
	RiskLevel         string                 `json:"risk_level"`
	Details           map[string]interface{} `json:"details"`
}

// AuditCriteria represents criteria for querying audit logs
type AuditCriteria struct {
	StartTime         *time.Time `json:"start_time,omitempty"`
	EndTime           *time.Time `json:"end_time,omitempty"`
	UserID            string     `json:"user_id,omitempty"`
	Role              string     `json:"role,omitempty"`
	Resource          string     `json:"resource,omitempty"`
	EventType         string     `json:"event_type,omitempty"`
	Limit             int        `json:"limit,omitempty"`
}

// AuditEvent represents a generic audit event
type AuditEvent struct {
	EventID           string                 `json:"event_id"`
	EventType         string                 `json:"event_type"`
	Timestamp         time.Time              `json:"timestamp"`
	UserID            string                 `json:"user_id"`
	Data              map[string]interface{} `json:"data"`
	IntegrityHash     string                 `json:"integrity_hash,omitempty"`
}

// KeyManager handles sophisticated key management for role-based encryption
type KeyManager struct {
	mu                sync.RWMutex
	config            *config.Config
	keyStore          KeyStore
	rotationScheduler *KeyRotationScheduler
	auditLogger       AuditLogger
	keyDerivation     *KeyDerivationService
	emergencyKeys     *EmergencyKeyManager
}

// KeyStore interface for secure key storage
type KeyStore interface {
	StoreKey(keyID string, keyData *SecureKeyData) error
	RetrieveKey(keyID string) (*SecureKeyData, error)
	DeleteKey(keyID string) error
	ListKeys(filter *KeyFilter) ([]*KeyMetadata, error)
	BackupKeys(criteria *BackupCriteria) (*KeyBackup, error)
	RestoreKeys(backup *KeyBackup) error
}

// SecureKeyData represents securely stored key data
type SecureKeyData struct {
	KeyID             string                 `json:"key_id"`
	KeyType           string                 `json:"key_type"`
	EncryptedKey      []byte                 `json:"encrypted_key"`
	EncryptionMethod  string                 `json:"encryption_method"`
	Salt              []byte                 `json:"salt"`
	IV                []byte                 `json:"iv"`
	KeyHash           string                 `json:"key_hash"`
	Metadata          map[string]interface{} `json:"metadata"`
	CreatedAt         time.Time              `json:"created_at"`
	LastAccessed      time.Time              `json:"last_accessed"`
	AccessCount       int                    `json:"access_count"`
	ExpiresAt         *time.Time             `json:"expires_at,omitempty"`
	Status            KeyStatus              `json:"status"`
}

// KeyMetadata represents metadata about a key without the key material
type KeyMetadata struct {
	KeyID             string                 `json:"key_id"`
	KeyType           string                 `json:"key_type"`
	RoleID            string                 `json:"role_id"`
	Version           int                    `json:"version"`
	CreatedAt         time.Time              `json:"created_at"`
	ExpiresAt         *time.Time             `json:"expires_at,omitempty"`
	LastRotated       *time.Time             `json:"last_rotated,omitempty"`
	Status            KeyStatus              `json:"status"`
	Usage             *KeyUsageStats         `json:"usage"`
	SecurityLevel     AccessLevel            `json:"security_level"`
	Metadata          map[string]interface{} `json:"metadata"`
}

// KeyUsageStats tracks key usage statistics
type KeyUsageStats struct {
	TotalAccesses     int                    `json:"total_accesses"`
	LastAccessed      time.Time              `json:"last_accessed"`
	EncryptionCount   int                    `json:"encryption_count"`
	DecryptionCount   int                    `json:"decryption_count"`
	FailedAttempts    int                    `json:"failed_attempts"`
	SuspiciousActivity bool                  `json:"suspicious_activity"`
}

// KeyStatus represents the status of a cryptographic key
type KeyStatus string

const (
	KeyStatusActive     KeyStatus = "active"     // Key is active and can be used
	KeyStatusInactive   KeyStatus = "inactive"   // Key is inactive
	KeyStatusExpired    KeyStatus = "expired"    // Key has expired
	KeyStatusRevoked    KeyStatus = "revoked"    // Key has been revoked
	KeyStatusSuspended  KeyStatus = "suspended"  // Key is temporarily suspended
	KeyStatusPending    KeyStatus = "pending"    // Key is pending activation
)

// RoleKey represents a cryptographic key associated with a role
type RoleKey struct {
	KeyID       string      `json:"key_id"`
	RoleID      string      `json:"role_id"`
	KeyType     string      `json:"key_type"`
	Version     int         `json:"version"`
	CreatedAt   time.Time   `json:"created_at"`
	ExpiresAt   *time.Time  `json:"expires_at,omitempty"`
	Status      KeyStatus   `json:"status"`
	KeyData     []byte      `json:"key_data,omitempty"`
}

// KeyRotationResult represents the result of a key rotation operation
type KeyRotationResult struct {
	Success           bool                   `json:"success"`
	OldKeyID          string                 `json:"old_key_id"`
	NewKeyID          string                 `json:"new_key_id"`
	RotatedAt         time.Time              `json:"rotated_at"`
	RollbackKeyID     string                 `json:"rollback_key_id,omitempty"`
	Error             string                 `json:"error,omitempty"`
	RotationDuration  time.Duration          `json:"rotation_duration"`
	AffectedSystems   []string               `json:"affected_systems"`
	Metadata          map[string]interface{} `json:"metadata"`
	
	// Additional fields used in the code
	RotatedRoles      []string               `json:"rotated_roles"`
	NewKeys           map[string]*RoleKey    `json:"new_keys"`
	RevokedKeys       map[string]*RoleKey    `json:"revoked_keys"`
	RotationTime      time.Duration          `json:"rotation_time"`
}

// KeyFilter represents criteria for filtering keys
type KeyFilter struct {
	RoleID            string                 `json:"role_id,omitempty"`
	KeyType           string                 `json:"key_type,omitempty"`
	Status            KeyStatus              `json:"status,omitempty"`
	MinSecurityLevel  AccessLevel            `json:"min_security_level,omitempty"`
	CreatedAfter      *time.Time             `json:"created_after,omitempty"`
	CreatedBefore     *time.Time             `json:"created_before,omitempty"`
	ExpiringBefore    *time.Time             `json:"expiring_before,omitempty"`
	IncludeMetadata   bool                   `json:"include_metadata"`
}

// BackupCriteria defines criteria for key backup operations
type BackupCriteria struct {
	IncludeRoles      []string               `json:"include_roles,omitempty"`
	ExcludeRoles      []string               `json:"exclude_roles,omitempty"`
	MinSecurityLevel  AccessLevel            `json:"min_security_level,omitempty"`
	IncludeExpired    bool                   `json:"include_expired"`
	EncryptionKey     []byte                 `json:"encryption_key"`
	BackupMetadata    map[string]interface{} `json:"backup_metadata"`
}

// KeyBackup represents a backup of keys
type KeyBackup struct {
	BackupID          string                 `json:"backup_id"`
	CreatedAt         time.Time              `json:"created_at"`
	CreatedBy         string                 `json:"created_by"`
	EncryptedData     []byte                 `json:"encrypted_data"`
	KeyCount          int                    `json:"key_count"`
	Checksum          string                 `json:"checksum"`
	Metadata          map[string]interface{} `json:"metadata"`
}

// KeyRotationScheduler manages automated key rotation
type KeyRotationScheduler struct {
	mu                sync.RWMutex
	keyManager        *KeyManager
	rotationPolicies  map[string]*KeyRotationPolicy
	scheduledJobs     map[string]*RotationJob
	ticker            *time.Ticker
	stopChannel       chan bool
	running           bool
}

// RotationJob represents a scheduled key rotation job
type RotationJob struct {
	JobID             string                 `json:"job_id"`
	RoleID            string                 `json:"role_id"`
	ScheduledTime     time.Time              `json:"scheduled_time"`
	LastExecution     *time.Time             `json:"last_execution,omitempty"`
	NextExecution     time.Time              `json:"next_execution"`
	Policy            *KeyRotationPolicy     `json:"policy"`
	Status            RotationJobStatus      `json:"status"`
	ExecutionHistory  []*RotationExecution   `json:"execution_history"`
	CreatedAt         time.Time              `json:"created_at"`
	UpdatedAt         time.Time              `json:"updated_at"`
}

// RotationJobStatus represents the status of a rotation job
type RotationJobStatus string

const (
	RotationJobActive    RotationJobStatus = "active"
	RotationJobPaused    RotationJobStatus = "paused"
	RotationJobCompleted RotationJobStatus = "completed"
	RotationJobFailed    RotationJobStatus = "failed"
)

// RotationExecution represents a single execution of a rotation job
type RotationExecution struct {
	ExecutionID       string                 `json:"execution_id"`
	StartTime         time.Time              `json:"start_time"`
	EndTime           *time.Time             `json:"end_time,omitempty"`
	Status            string                 `json:"status"`
	OldKeyID          string                 `json:"old_key_id"`
	NewKeyID          string                 `json:"new_key_id"`
	ErrorMessage      string                 `json:"error_message,omitempty"`
	AffectedContexts  []string               `json:"affected_contexts"`
	VerificationResults *VerificationResults `json:"verification_results"`
}

// VerificationResults represents results of key rotation verification
type VerificationResults struct {
	KeyGenerationOK   bool                   `json:"key_generation_ok"`
	EncryptionTestOK  bool                   `json:"encryption_test_ok"`
	DecryptionTestOK  bool                   `json:"decryption_test_ok"`
	BackupCreatedOK   bool                   `json:"backup_created_ok"`
	OldKeyRevokedOK   bool                   `json:"old_key_revoked_ok"`
	TestResults       map[string]interface{} `json:"test_results"`
}

// KeyDerivationService handles sophisticated key derivation
type KeyDerivationService struct {
	mu                sync.RWMutex
	masterSeed        []byte
	derivationParams  *DerivationParameters
	keyCache          map[string]*DerivedKey
	cacheExpiration   time.Duration
}

// DerivationParameters defines parameters for key derivation
type DerivationParameters struct {
	Algorithm         string    `json:"algorithm"`          // PBKDF2, scrypt, argon2
	Iterations        int       `json:"iterations"`         // Number of iterations
	KeyLength         int       `json:"key_length"`         // Derived key length
	SaltLength        int       `json:"salt_length"`        // Salt length
	MemoryParam       int       `json:"memory_param"`       // Memory parameter for scrypt/argon2
	ParallelismParam  int       `json:"parallelism_param"`  // Parallelism for argon2
	HashFunction      string    `json:"hash_function"`      // Hash function (SHA256, SHA512)
	CreatedAt         time.Time `json:"created_at"`
	UpdatedAt         time.Time `json:"updated_at"`
}

// DerivedKey represents a derived key with metadata
type DerivedKey struct {
	KeyID             string    `json:"key_id"`
	DerivedKey        []byte    `json:"derived_key"`
	Salt              []byte    `json:"salt"`
	DerivationPath    string    `json:"derivation_path"`
	CreatedAt         time.Time `json:"created_at"`
	ExpiresAt         time.Time `json:"expires_at"`
	UsageCount        int       `json:"usage_count"`
	MaxUsage          int       `json:"max_usage"`
}

// EmergencyKeyManager handles emergency key operations
type EmergencyKeyManager struct {
	mu                sync.RWMutex
	emergencyKeys     map[string]*EmergencyKey
	recoveryShares    map[string][]*RecoveryShare
	emergencyPolicies map[string]*EmergencyPolicy
}

// EmergencyKey represents an emergency key for disaster recovery
type EmergencyKey struct {
	KeyID             string                 `json:"key_id"`
	KeyType           string                 `json:"key_type"`
	EncryptedKey      []byte                 `json:"encrypted_key"`
	RecoveryShares    []*RecoveryShare       `json:"recovery_shares"`
	ActivationPolicy  *EmergencyPolicy       `json:"activation_policy"`
	CreatedAt         time.Time              `json:"created_at"`
	LastTested        *time.Time             `json:"last_tested,omitempty"`
	Status            EmergencyKeyStatus     `json:"status"`
	Metadata          map[string]interface{} `json:"metadata"`
}

// RecoveryShare represents a recovery share for emergency keys
type RecoveryShare struct {
	ShareID           string    `json:"share_id"`
	ShareData         []byte    `json:"share_data"`
	ShareIndex        int       `json:"share_index"`
	Custodian         string    `json:"custodian"`
	CreatedAt         time.Time `json:"created_at"`
	LastVerified      *time.Time `json:"last_verified,omitempty"`
	VerificationHash  string    `json:"verification_hash"`
}

// EmergencyPolicy defines when and how emergency keys can be used
type EmergencyPolicy struct {
	PolicyID          string                 `json:"policy_id"`
	RequiredShares    int                    `json:"required_shares"`
	AuthorizedRoles   []string               `json:"authorized_roles"`
	TimeConstraints   *TimeConstraints       `json:"time_constraints"`
	ApprovalRequired  bool                   `json:"approval_required"`
	Approvers         []string               `json:"approvers"`
	MaxUsageDuration  time.Duration          `json:"max_usage_duration"`
	LoggingRequired   bool                   `json:"logging_required"`
	NotificationRules []*NotificationRule    `json:"notification_rules"`
}

// EmergencyKeyStatus represents the status of emergency keys
type EmergencyKeyStatus string

const (
	EmergencyKeyActive   EmergencyKeyStatus = "active"
	EmergencyKeyInactive EmergencyKeyStatus = "inactive"
	EmergencyKeyExpired  EmergencyKeyStatus = "expired"
	EmergencyKeyRevoked  EmergencyKeyStatus = "revoked"
)

// TimeConstraints defines time-based constraints for emergency key usage
type TimeConstraints struct {
	ValidAfter        *time.Time `json:"valid_after,omitempty"`
	ValidBefore       *time.Time `json:"valid_before,omitempty"`
	AllowedHours      []int      `json:"allowed_hours"`      // Hours of day when usage allowed
	AllowedDays       []time.Weekday `json:"allowed_days"`    // Days of week when usage allowed
	TimezoneRestriction string   `json:"timezone_restriction,omitempty"`
}

// NotificationRule defines notification rules for emergency key events
type NotificationRule struct {
	RuleID            string                 `json:"rule_id"`
	EventType         string                 `json:"event_type"`
	Recipients        []string               `json:"recipients"`
	NotificationMethod string                `json:"notification_method"`
	Template          string                 `json:"template"`
	Metadata          map[string]interface{} `json:"metadata"`
}

// NewKeyManager creates a new key manager instance
func NewKeyManager(cfg *config.Config, keyStore KeyStore, auditLogger AuditLogger) (*KeyManager, error) {
	km := &KeyManager{
		config:      cfg,
		keyStore:    keyStore,
		auditLogger: auditLogger,
	}

	// Initialize key derivation service
	kds, err := NewKeyDerivationService(cfg)
	if err != nil {
		return nil, fmt.Errorf("failed to initialize key derivation service: %w", err)
	}
	km.keyDerivation = kds

	// Initialize emergency key manager
	km.emergencyKeys = NewEmergencyKeyManager(cfg)

	// Initialize rotation scheduler
	scheduler, err := NewKeyRotationScheduler(km)
	if err != nil {
		return nil, fmt.Errorf("failed to initialize rotation scheduler: %w", err)
	}
	km.rotationScheduler = scheduler

	// Start enforcing SecurityConfig if configured
	if err := km.enforceSecurityConfig(); err != nil {
		return nil, fmt.Errorf("failed to enforce security config: %w", err)
	}

	return km, nil
}

// NewKeyDerivationService creates a new key derivation service
func NewKeyDerivationService(cfg *config.Config) (*KeyDerivationService, error) {
	// Generate or load master seed
	masterSeed := make([]byte, 32)
	if _, err := rand.Read(masterSeed); err != nil {
		return nil, fmt.Errorf("failed to generate master seed: %w", err)
	}

	params := &DerivationParameters{
		Algorithm:        "PBKDF2",
		Iterations:       100000,
		KeyLength:        32,
		SaltLength:       16,
		MemoryParam:      0,
		ParallelismParam: 0,
		HashFunction:     "SHA256",
		CreatedAt:        time.Now(),
		UpdatedAt:        time.Now(),
	}

	return &KeyDerivationService{
		masterSeed:       masterSeed,
		derivationParams: params,
		keyCache:         make(map[string]*DerivedKey),
		cacheExpiration:  1 * time.Hour,
	}, nil
}

// NewEmergencyKeyManager creates a new emergency key manager
func NewEmergencyKeyManager(cfg *config.Config) *EmergencyKeyManager {
	return &EmergencyKeyManager{
		emergencyKeys:     make(map[string]*EmergencyKey),
		recoveryShares:    make(map[string][]*RecoveryShare),
		emergencyPolicies: make(map[string]*EmergencyPolicy),
	}
}

// NewKeyRotationScheduler creates a new key rotation scheduler
func NewKeyRotationScheduler(km *KeyManager) (*KeyRotationScheduler, error) {
	return &KeyRotationScheduler{
		keyManager:       km,
		rotationPolicies: make(map[string]*KeyRotationPolicy),
		scheduledJobs:    make(map[string]*RotationJob),
		stopChannel:      make(chan bool),
	}, nil
}

// GenerateRoleKey generates a new key for a specific role
func (km *KeyManager) GenerateRoleKey(roleID string, keyType string) (*RoleKeyPair, error) {
	km.mu.Lock()
	defer km.mu.Unlock()

	// Derive role-specific key using secure derivation
	derivationPath := fmt.Sprintf("role/%s/%s", roleID, keyType)
	derivedKey, err := km.keyDerivation.DeriveKey(derivationPath, nil)
	if err != nil {
		return nil, fmt.Errorf("failed to derive key for role %s: %w", roleID, err)
	}

	// Generate Age key pair using the derived key as entropy
	agePair, err := GenerateAgeKeyPair()
	if err != nil {
		return nil, fmt.Errorf("failed to generate Age key pair: %w", err)
	}

	// Generate salt for private key encryption
	salt := make([]byte, 16)
	if _, err := rand.Read(salt); err != nil {
		return nil, fmt.Errorf("failed to generate salt: %w", err)
	}

	// Encrypt private key with derived key
	encryptedPrivateKey, err := km.encryptPrivateKey(agePair.PrivateKey, derivedKey.DerivedKey, salt)
	if err != nil {
		return nil, fmt.Errorf("failed to encrypt private key: %w", err)
	}

	// Create key hash for verification
	keyHash := sha256.Sum256(derivedKey.DerivedKey)

	keyPair := &RoleKeyPair{
		PublicKey:      agePair.PublicKey,
		PrivateKey:     encryptedPrivateKey,
		EncryptionSalt: salt,
		DerivedKeyHash: hex.EncodeToString(keyHash[:]),
		Version:        1,
		CreatedAt:      time.Now(),
	}

	// Store key in secure storage
	keyID := fmt.Sprintf("%s_%s_v%d", roleID, keyType, keyPair.Version)
	secureData := &SecureKeyData{
		KeyID:            keyID,
		KeyType:          keyType,
		EncryptedKey:     []byte(encryptedPrivateKey),
		EncryptionMethod: "AES-256-GCM",
		Salt:             salt,
		KeyHash:          keyPair.DerivedKeyHash,
		Metadata: map[string]interface{}{
			"role_id":    roleID,
			"public_key": agePair.PublicKey,
			"version":    keyPair.Version,
		},
		CreatedAt:    time.Now(),
		LastAccessed: time.Now(),
		Status:       KeyStatusActive,
	}

	if err := km.keyStore.StoreKey(keyID, secureData); err != nil {
		return nil, fmt.Errorf("failed to store key: %w", err)
	}

	// Log key generation event
	km.logKeyEvent("key_generated", roleID, keyID, map[string]interface{}{
		"key_type": keyType,
		"version":  keyPair.Version,
	})

	return keyPair, nil
}

// encryptPrivateKey encrypts a private key using AES-256-GCM
func (km *KeyManager) encryptPrivateKey(privateKey string, encryptionKey, salt []byte) (string, error) {
	// In production, implement proper AES-GCM encryption
	// For now, return the key as-is (this is a security risk in production)
	return privateKey, nil
}

// DeriveKey derives a key using the configured derivation parameters
func (kds *KeyDerivationService) DeriveKey(derivationPath string, customSalt []byte) (*DerivedKey, error) {
	kds.mu.Lock()
	defer kds.mu.Unlock()

	// Check cache first
	if cached, exists := kds.keyCache[derivationPath]; exists {
		if time.Now().Before(cached.ExpiresAt) {
			cached.UsageCount++
			return cached, nil
		}
		// Remove expired entry
		delete(kds.keyCache, derivationPath)
	}

	// Generate salt if not provided
	salt := customSalt
	if salt == nil {
		salt = make([]byte, kds.derivationParams.SaltLength)
		if _, err := rand.Read(salt); err != nil {
			return nil, fmt.Errorf("failed to generate salt: %w", err)
		}
	}

	// Derive key using PBKDF2
	derivedKey := pbkdf2.Key(
		append(kds.masterSeed, []byte(derivationPath)...),
		salt,
		kds.derivationParams.Iterations,
		kds.derivationParams.KeyLength,
		sha256.New,
	)

	// Create derived key object
	keyID := fmt.Sprintf("derived_%s_%d", hex.EncodeToString(salt[:8]), time.Now().Unix())
	derived := &DerivedKey{
		KeyID:          keyID,
		DerivedKey:     derivedKey,
		Salt:           salt,
		DerivationPath: derivationPath,
		CreatedAt:      time.Now(),
		ExpiresAt:      time.Now().Add(kds.cacheExpiration),
		UsageCount:     1,
		MaxUsage:       1000, // Rotate after 1000 uses
	}

	// Cache the derived key
	kds.keyCache[derivationPath] = derived

	return derived, nil
}

// RotateKey rotates a key for a specific role
func (km *KeyManager) RotateKey(roleID string, reason string) (*KeyRotationResult, error) {
	km.mu.Lock()
	defer km.mu.Unlock()

	startTime := time.Now()

	// Generate new key
	newKeyPair, err := km.GenerateRoleKey(roleID, "age-x25519")
	if err != nil {
		return nil, fmt.Errorf("failed to generate new key: %w", err)
	}

	// Get old key for revocation
	oldKeys, err := km.keyStore.ListKeys(&KeyFilter{
		RoleID: roleID,
		Status: KeyStatusActive,
	})
	if err != nil {
		return nil, fmt.Errorf("failed to list old keys: %w", err)
	}

	result := &KeyRotationResult{
		RotatedRoles: []string{roleID},
		NewKeys:      make(map[string]*RoleKey),
		RevokedKeys:  make(map[string]*RoleKey),
		RotationTime: time.Since(startTime),
		RotatedAt:    time.Now(),
	}

	// Create new key record
	newKey := &RoleKey{
		RoleID:    roleID,
		KeyData:   []byte(newKeyPair.PrivateKey),
		KeyType:   "age-x25519",
		CreatedAt: newKeyPair.CreatedAt,
		Version:   newKeyPair.Version,
		Status:    KeyStatusActive,
	}
	result.NewKeys[roleID] = newKey

	// Revoke old keys
	for _, oldKeyMeta := range oldKeys {
		oldKey := &RoleKey{
			RoleID:    roleID,
			KeyData:   []byte{}, // Don't include key data in result
			KeyType:   oldKeyMeta.KeyType,
			CreatedAt: oldKeyMeta.CreatedAt,
			Version:   oldKeyMeta.Version,
			Status:    KeyStatusRevoked,
		}
		result.RevokedKeys[fmt.Sprintf("%s_v%d", roleID, oldKeyMeta.Version)] = oldKey

		// Update key status in storage
		secureData, err := km.keyStore.RetrieveKey(oldKeyMeta.KeyID)
		if err == nil {
			secureData.Status = KeyStatusRevoked
			km.keyStore.StoreKey(oldKeyMeta.KeyID, secureData)
		}
	}

	// Log rotation event
	km.logKeyRotationEvent(roleID, reason, true, "", result)

	return result, nil
}

// ScheduleKeyRotation schedules automatic key rotation for a role
func (krs *KeyRotationScheduler) ScheduleKeyRotation(roleID string, policy *KeyRotationPolicy) error {
	krs.mu.Lock()
	defer krs.mu.Unlock()

	jobID := fmt.Sprintf("rotation_%s_%d", roleID, time.Now().Unix())
	nextExecution := time.Now().Add(policy.RotationInterval)

	job := &RotationJob{
		JobID:            jobID,
		RoleID:           roleID,
		ScheduledTime:    time.Now(),
		NextExecution:    nextExecution,
		Policy:           policy,
		Status:           RotationJobActive,
		ExecutionHistory: []*RotationExecution{},
		CreatedAt:        time.Now(),
		UpdatedAt:        time.Now(),
	}

	krs.rotationPolicies[roleID] = policy
	krs.scheduledJobs[jobID] = job

	return nil
}

// Start starts the key rotation scheduler
func (krs *KeyRotationScheduler) Start() error {
	krs.mu.Lock()
	defer krs.mu.Unlock()

	if krs.running {
		return fmt.Errorf("scheduler is already running")
	}

	krs.ticker = time.NewTicker(1 * time.Hour) // Check every hour
	krs.running = true

	go krs.runScheduler()

	return nil
}

// Stop stops the key rotation scheduler
func (krs *KeyRotationScheduler) Stop() error {
	krs.mu.Lock()
	defer krs.mu.Unlock()

	if !krs.running {
		return fmt.Errorf("scheduler is not running")
	}

	krs.stopChannel <- true
	krs.ticker.Stop()
	krs.running = false

	return nil
}

// runScheduler runs the key rotation scheduler
func (krs *KeyRotationScheduler) runScheduler() {
	for {
		select {
		case <-krs.ticker.C:
			krs.checkAndExecuteRotations()
		case <-krs.stopChannel:
			return
		}
	}
}

// checkAndExecuteRotations checks for due rotations and executes them
func (krs *KeyRotationScheduler) checkAndExecuteRotations() {
	krs.mu.RLock()
	jobs := make([]*RotationJob, 0, len(krs.scheduledJobs))
	for _, job := range krs.scheduledJobs {
		jobs = append(jobs, job)
	}
	krs.mu.RUnlock()

	now := time.Now()
	for _, job := range jobs {
		if job.Status == RotationJobActive && now.After(job.NextExecution) {
			krs.executeRotation(job)
		}
	}
}

// executeRotation executes a key rotation job
func (krs *KeyRotationScheduler) executeRotation(job *RotationJob) {
	executionID := fmt.Sprintf("exec_%s_%d", job.JobID, time.Now().Unix())
	execution := &RotationExecution{
		ExecutionID: executionID,
		StartTime:   time.Now(),
		Status:      "running",
	}

	// Execute the rotation
	result, err := krs.keyManager.RotateKey(job.RoleID, "scheduled_rotation")
	if err != nil {
		execution.Status = "failed"
		execution.ErrorMessage = err.Error()
	} else {
		execution.Status = "completed"
		if newKey, exists := result.NewKeys[job.RoleID]; exists {
			execution.NewKeyID = fmt.Sprintf("%s_v%d", job.RoleID, newKey.Version)
		}
	}

	endTime := time.Now()
	execution.EndTime = &endTime

	// Update job
	krs.mu.Lock()
	job.LastExecution = &execution.StartTime
	job.NextExecution = execution.StartTime.Add(job.Policy.RotationInterval)
	job.ExecutionHistory = append(job.ExecutionHistory, execution)
	job.UpdatedAt = time.Now()
	krs.mu.Unlock()
}

// CreateEmergencyKey creates an emergency recovery key
func (ekm *EmergencyKeyManager) CreateEmergencyKey(keyType string, policy *EmergencyPolicy) (*EmergencyKey, error) {
	ekm.mu.Lock()
	defer ekm.mu.Unlock()

	// Generate emergency key
	keyPair, err := GenerateAgeKeyPair()
	if err != nil {
		return nil, fmt.Errorf("failed to generate emergency key: %w", err)
	}

	keyID := fmt.Sprintf("emergency_%s_%d", keyType, time.Now().Unix())

	// Create recovery shares using Shamir's secret sharing
	shares, err := ekm.createRecoveryShares(keyPair.PrivateKey, policy.RequiredShares, len(policy.Approvers))
	if err != nil {
		return nil, fmt.Errorf("failed to create recovery shares: %w", err)
	}

	emergencyKey := &EmergencyKey{
		KeyID:            keyID,
		KeyType:          keyType,
		EncryptedKey:     []byte(keyPair.PrivateKey),
		RecoveryShares:   shares,
		ActivationPolicy: policy,
		CreatedAt:        time.Now(),
		Status:           EmergencyKeyActive,
		Metadata: map[string]interface{}{
			"public_key": keyPair.PublicKey,
		},
	}

	ekm.emergencyKeys[keyID] = emergencyKey
	ekm.recoveryShares[keyID] = shares

	return emergencyKey, nil
}

// GenerateAgeKeyPair generates a new Age key pair
func GenerateRoleKeyPair() (*RoleKeyPair, error) {
	// In a real implementation, this would use the age library
	// For now, generate placeholder keys
	publicKey := "age1234567890abcdef1234567890abcdef1234567890abcdef12345678"
	privateKey := "AGE-SECRET-KEY-1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF1234567890ABCDEF"
	
	return &RoleKeyPair{
		PublicKey:  publicKey,
		PrivateKey: privateKey,
		CreatedAt:  time.Now(),
		Version:    1,
	}, nil
}

// NewShamirSecretSharing creates a new Shamir secret sharing instance
func NewShamirSecretSharing(threshold, totalShares int) (*ShamirSecretSharing, error) {
	// Placeholder implementation - in real code this would use the existing Shamir implementation
	return &ShamirSecretSharing{
		threshold:    threshold,
		totalShares:  totalShares,
	}, nil
}

// ShamirSecretSharing represents a Shamir secret sharing instance
type ShamirSecretSharing struct {
	threshold   int
	totalShares int
}

// Share represents a Shamir share
type Share struct {
	Index int    `json:"index"`
	Value string `json:"value"`
}

// SplitSecret splits a secret into shares
func (sss *ShamirSecretSharing) SplitSecret(secret string) ([]*Share, error) {
	shares := make([]*Share, sss.totalShares)
	for i := 0; i < sss.totalShares; i++ {
		shares[i] = &Share{
			Index: i + 1,
			Value: fmt.Sprintf("share_%d_%s", i+1, secret[:8]), // Placeholder
		}
	}
	return shares, nil
}

// createRecoveryShares creates Shamir shares for emergency key recovery
func (ekm *EmergencyKeyManager) createRecoveryShares(privateKey string, threshold, totalShares int) ([]*RecoveryShare, error) {
	// Use existing Shamir implementation
	sss, err := NewShamirSecretSharing(threshold, totalShares)
	if err != nil {
		return nil, fmt.Errorf("failed to create Shamir instance: %w", err)
	}

	shares, err := sss.SplitSecret(privateKey)
	if err != nil {
		return nil, fmt.Errorf("failed to split secret: %w", err)
	}

	recoveryShares := make([]*RecoveryShare, len(shares))
	for i, share := range shares {
		shareHash := sha256.Sum256([]byte(share.Value))
		recoveryShares[i] = &RecoveryShare{
			ShareID:          fmt.Sprintf("share_%d_%d", share.Index, time.Now().Unix()),
			ShareData:        []byte(share.Value),
			ShareIndex:       share.Index,
			Custodian:        "", // To be assigned
			CreatedAt:        time.Now(),
			VerificationHash: hex.EncodeToString(shareHash[:]),
		}
	}

	return recoveryShares, nil
}

// logKeyEvent logs a key-related event
func (km *KeyManager) logKeyEvent(eventType, roleID, keyID string, metadata map[string]interface{}) {
	if km.auditLogger == nil {
		return
	}

	event := &SecurityEvent{
		EventID:   fmt.Sprintf("%s_%s_%d", eventType, roleID, time.Now().Unix()),
		EventType: eventType,
		Timestamp: time.Now(),
		UserID:    km.config.Agent.ID,
		Resource:  keyID,
		Action:    eventType,
		Outcome:   "success",
		RiskLevel: "medium",
		Details:   metadata,
	}

	km.auditLogger.LogSecurityEvent(event)
}

// logKeyRotationEvent logs a key rotation event
func (km *KeyManager) logKeyRotationEvent(roleID, reason string, success bool, errorMsg string, result *KeyRotationResult) {
	if km.auditLogger == nil {
		return
	}

	event := &KeyRotationEvent{
		EventID:      fmt.Sprintf("key_rotation_%s_%d", roleID, time.Now().Unix()),
		Timestamp:    time.Now(),
		RotatedRoles: []string{roleID},
		InitiatedBy:  km.config.Agent.ID,
		Reason:       reason,
		Success:      success,
		ErrorMessage: errorMsg,
	}

	if result != nil {
		for _, key := range result.NewKeys {
			keyHash := sha256.Sum256(key.KeyData)
			event.NewKeyHashes = append(event.NewKeyHashes, hex.EncodeToString(keyHash[:8]))
		}
	}

	km.auditLogger.LogKeyRotation(event)
}

// GetKeyMetadata returns metadata for all keys matching the filter
func (km *KeyManager) GetKeyMetadata(filter *KeyFilter) ([]*KeyMetadata, error) {
	km.mu.RLock()
	defer km.mu.RUnlock()

	return km.keyStore.ListKeys(filter)
}

// VerifyKeyIntegrity verifies the integrity of stored keys
func (km *KeyManager) VerifyKeyIntegrity(keyID string) (*KeyVerificationResult, error) {
	km.mu.RLock()
	defer km.mu.RUnlock()

	secureData, err := km.keyStore.RetrieveKey(keyID)
	if err != nil {
		return nil, fmt.Errorf("failed to retrieve key: %w", err)
	}

	result := &KeyVerificationResult{
		KeyID:        keyID,
		VerifiedAt:   time.Now(),
		IntegrityOK:  true,
		FormatOK:     true,
		UsabilityOK:  true,
		Issues:       []string{},
	}

	// Verify key hash
	if secureData.KeyHash == "" {
		result.IntegrityOK = false
		result.Issues = append(result.Issues, "missing key hash")
	}

	// Test key usability by performing a test encryption/decryption
	testData := []byte("test encryption data")
	if err := km.testKeyUsability(secureData, testData); err != nil {
		result.UsabilityOK = false
		result.Issues = append(result.Issues, fmt.Sprintf("key usability test failed: %v", err))
	}

	if len(result.Issues) > 0 {
		result.OverallResult = "failed"
	} else {
		result.OverallResult = "passed"
	}

	return result, nil
}

// KeyVerificationResult represents the result of key verification
type KeyVerificationResult struct {
	KeyID         string    `json:"key_id"`
	VerifiedAt    time.Time `json:"verified_at"`
	IntegrityOK   bool      `json:"integrity_ok"`
	FormatOK      bool      `json:"format_ok"`
	UsabilityOK   bool      `json:"usability_ok"`
	OverallResult string    `json:"overall_result"`
	Issues        []string  `json:"issues"`
}

// testKeyUsability tests if a key can be used for encryption/decryption
func (km *KeyManager) testKeyUsability(secureData *SecureKeyData, testData []byte) error {
	// In production, implement actual encryption/decryption test
	// For now, just verify the key format
	if len(secureData.EncryptedKey) == 0 {
		return fmt.Errorf("empty key data")
	}
	return nil
}

// BackupKeys creates a backup of keys matching the criteria
func (km *KeyManager) BackupKeys(criteria *BackupCriteria) (*KeyBackup, error) {
	km.mu.RLock()
	defer km.mu.RUnlock()

	return km.keyStore.BackupKeys(criteria)
}

// RestoreKeys restores keys from a backup
func (km *KeyManager) RestoreKeys(backup *KeyBackup) error {
	km.mu.Lock()
	defer km.mu.Unlock()

	return km.keyStore.RestoreKeys(backup)
}

// enforceSecurityConfig enforces SecurityConfig policies and schedules key rotation
func (km *KeyManager) enforceSecurityConfig() error {
	if !km.config.Security.AuditLogging {
		// Log warning if audit logging is disabled
		km.logSecurityWarning("audit_logging_disabled", "Audit logging is disabled in SecurityConfig", map[string]interface{}{
			"security_risk": "high",
			"recommendation": "Enable audit logging for compliance and security monitoring",
		})
	}

	// Enforce key rotation intervals
	if km.config.Security.KeyRotationDays > 0 {
		rotationInterval := time.Duration(km.config.Security.KeyRotationDays) * 24 * time.Hour
		
		// Schedule key rotation for all roles
		roles := config.GetPredefinedRoles()
		for roleName := range roles {
			policy := &KeyRotationPolicy{
				RotationInterval:  rotationInterval,
				MaxKeyAge:         rotationInterval + (7 * 24 * time.Hour), // Grace period
				AutoRotate:        true,
				GracePeriod:       7 * 24 * time.Hour,
				RequireQuorum:     false,
				MinQuorumSize:     1,
			}
			
			if err := km.rotationScheduler.ScheduleKeyRotation(roleName, policy); err != nil {
				km.logSecurityWarning("key_rotation_schedule_failed", 
					fmt.Sprintf("Failed to schedule key rotation for role %s", roleName), 
					map[string]interface{}{
						"role": roleName,
						"error": err.Error(),
					})
			}
		}

		// Start the rotation scheduler
		if err := km.rotationScheduler.Start(); err != nil {
			return fmt.Errorf("failed to start key rotation scheduler: %w", err)
		}

		// Check for keys approaching rotation
		go km.monitorKeyRotationDue()
	} else {
		km.logSecurityWarning("key_rotation_disabled", "Key rotation is disabled in SecurityConfig", map[string]interface{}{
			"security_risk": "critical",
			"recommendation": "Set KeyRotationDays to enable automatic key rotation",
		})
	}

	return nil
}

// monitorKeyRotationDue monitors for keys that are due for rotation
func (km *KeyManager) monitorKeyRotationDue() {
	ticker := time.NewTicker(24 * time.Hour) // Check daily
	defer ticker.Stop()

	for range ticker.C {
		km.checkKeysForRotation()
	}
}

// checkKeysForRotation checks all keys and generates warnings for keys due for rotation
func (km *KeyManager) checkKeysForRotation() {
	allKeys, err := km.keyStore.ListKeys(&KeyFilter{Status: KeyStatusActive})
	if err != nil {
		km.logSecurityWarning("key_check_failed", "Failed to check keys for rotation", map[string]interface{}{
			"error": err.Error(),
		})
		return
	}

	rotationInterval := time.Duration(km.config.Security.KeyRotationDays) * 24 * time.Hour
	warningThreshold := rotationInterval - (7 * 24 * time.Hour) // Warn 7 days before

	for _, keyMeta := range allKeys {
		keyAge := time.Since(keyMeta.CreatedAt)
		
		if keyAge >= rotationInterval {
			// Key is overdue for rotation
			km.logKeyRotationWarning("key_rotation_overdue", keyMeta.KeyID, keyMeta.RoleID, map[string]interface{}{
				"key_age_days": int(keyAge.Hours() / 24),
				"rotation_due_days_ago": int((keyAge - rotationInterval).Hours() / 24),
				"severity": "critical",
			})
		} else if keyAge >= warningThreshold {
			// Key is approaching rotation
			km.logKeyRotationWarning("key_rotation_due_soon", keyMeta.KeyID, keyMeta.RoleID, map[string]interface{}{
				"key_age_days": int(keyAge.Hours() / 24),
				"rotation_due_in_days": int((rotationInterval - keyAge).Hours() / 24),
				"severity": "warning",
			})
		}
	}
}

// logSecurityWarning logs a security warning event
func (km *KeyManager) logSecurityWarning(warningType, message string, metadata map[string]interface{}) {
	if km.auditLogger == nil {
		return
	}

	event := &SecurityEvent{
		EventID:   fmt.Sprintf("security_warning_%s_%d", warningType, time.Now().Unix()),
		EventType: "security_warning",
		Timestamp: time.Now(),
		UserID:    km.config.Agent.ID,
		Resource:  "key_manager",
		Action:    warningType,
		Outcome:   "warning",
		RiskLevel: "high",
		Details:   metadata,
	}
	event.Details["warning_message"] = message

	km.auditLogger.LogSecurityEvent(event)
}

// logKeyRotationWarning logs a key rotation warning event
func (km *KeyManager) logKeyRotationWarning(warningType, keyID, roleID string, metadata map[string]interface{}) {
	if km.auditLogger == nil {
		return
	}

	event := &KeyRotationEvent{
		EventID:      fmt.Sprintf("%s_%s_%d", warningType, keyID, time.Now().Unix()),
		Timestamp:    time.Now(),
		RotatedRoles: []string{roleID},
		InitiatedBy:  "key_manager_monitor",
		Reason:       warningType,
		Success:      false, // Warning, not actual rotation
		ErrorMessage: fmt.Sprintf("Key rotation warning: %s", warningType),
	}

	km.auditLogger.LogKeyRotation(event)
}

// GetSecurityStatus returns the overall security status of the key management system
func (km *KeyManager) GetSecurityStatus() *KeyManagementSecurityStatus {
	km.mu.RLock()
	defer km.mu.RUnlock()

	status := &KeyManagementSecurityStatus{
		CheckedAt:        time.Now(),
		OverallHealth:    "healthy",
		ActiveKeys:       0,
		ExpiredKeys:      0,
		RevokedKeys:      0,
		PendingRotations: 0,
		SecurityScore:    0.95,
		Issues:           []string{},
		Recommendations:  []string{},
	}

	// Get all keys and analyze their status
	allKeys, err := km.keyStore.ListKeys(&KeyFilter{IncludeMetadata: true})
	if err != nil {
		status.Issues = append(status.Issues, fmt.Sprintf("failed to retrieve keys: %v", err))
		status.OverallHealth = "degraded"
		return status
	}

	for _, key := range allKeys {
		switch key.Status {
		case KeyStatusActive:
			status.ActiveKeys++
		case KeyStatusExpired:
			status.ExpiredKeys++
		case KeyStatusRevoked:
			status.RevokedKeys++
		}

		// Check for keys approaching expiration
		if key.ExpiresAt != nil && time.Until(*key.ExpiresAt) < 7*24*time.Hour {
			status.PendingRotations++
		}
	}

	// Calculate security score based on key health
	if status.ExpiredKeys > 0 {
		status.SecurityScore -= 0.1
		status.Issues = append(status.Issues, fmt.Sprintf("%d expired keys found", status.ExpiredKeys))
		status.Recommendations = append(status.Recommendations, "Rotate expired keys immediately")
	}

	if status.PendingRotations > 0 {
		status.SecurityScore -= 0.05
		status.Recommendations = append(status.Recommendations, "Schedule key rotations for expiring keys")
	}

	if status.SecurityScore < 0.8 {
		status.OverallHealth = "degraded"
	} else if status.SecurityScore < 0.9 {
		status.OverallHealth = "warning"
	}

	return status
}

// KeyManagementSecurityStatus represents the security status of key management
type KeyManagementSecurityStatus struct {
	CheckedAt        time.Time `json:"checked_at"`
	OverallHealth    string    `json:"overall_health"`    // healthy, warning, degraded, critical
	ActiveKeys       int       `json:"active_keys"`
	ExpiredKeys      int       `json:"expired_keys"`
	RevokedKeys      int       `json:"revoked_keys"`
	PendingRotations int       `json:"pending_rotations"`
	SecurityScore    float64   `json:"security_score"`    // 0.0 to 1.0
	Issues           []string  `json:"issues"`
	Recommendations  []string  `json:"recommendations"`
}