//! The Elder Interface — Persona-based Automated Governance.
//! Implements Phase 10 [S5] Automated Evaluator Governance.

use async_trait::async_trait;
use mimirs_core::MimirError;
use serde::{Deserialize, Serialize};

/// CognitiveShift - A significant change to the cognitive manifold.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum CognitiveShift {
    /// Pruning dead modes from the wave field.
    WaveFieldPruning {
        /// Number of modes pruned.
        mode_count: usize,
    },
    /// Resolving a topological defect (knot).
    KnotResolution {
        /// Identifier of the memory at the center of the defect.
        center_id: mimirs_core::MemoryId,
    },
    /// Global manifold propagation update.
    ManifoldPropagation {
        /// Net change in von Neumann entropy.
        entropy_change: f32,
    },
}

/// EvaluatorPersona - Distinct architectural personas for governance.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub enum EvaluatorPersona {
    /// Focuses on mathematical rigor and topological integrity.
    Architect,
    /// Focuses on privacy leaks and manifold security.
    Security,
    /// Focuses on audit trails and verifiability compliance.
    Compliance,
}

/// Elder - A persona-based evaluator that can approve cognitive shifts.
#[async_trait]
pub trait Elder: Send + Sync {
    /// The persona this elder represents.
    fn persona(&self) -> EvaluatorPersona;

    /// Evaluates a proposed cognitive shift.
    /// Returns Ok(true) if approved, Ok(false) if rejected.
    async fn evaluate(&self, shift: &CognitiveShift) -> Result<bool, MimirError>;
}

/// ElderQuorum - Manages consensus among multiple persona evaluators.
pub struct ElderQuorum {
    elders: Vec<Box<dyn Elder>>,
}

impl Default for ElderQuorum {
    fn default() -> Self {
        Self::new()
    }
}

impl ElderQuorum {
    /// Creates a new empty ElderQuorum.
    pub fn new() -> Self {
        Self { elders: Vec::new() }
    }

    /// Attaches an elder evaluator to the quorum.
    pub fn attach_elder(&mut self, elder: Box<dyn Elder>) {
        self.elders.push(elder);
    }

    /// Requests consensus for a proposed cognitive shift.
    /// Requires at least one approval from each represented persona.
    pub async fn request_consensus(&self, shift: &CognitiveShift) -> Result<bool, MimirError> {
        let mut approvals = std::collections::HashSet::new();
        let mut total_required = std::collections::HashSet::new();

        for elder in &self.elders {
            total_required.insert(elder.persona());
            if elder.evaluate(shift).await? {
                approvals.insert(elder.persona());
            }
        }

        // QUORUM: Every represented persona must have at least one approval.
        Ok(approvals.len() == total_required.len() && !total_required.is_empty())
    }
}

/// Default Architects Evaluator (Lars Placeholder)
pub struct ArchitectElder;
#[async_trait]
impl Elder for ArchitectElder {
    fn persona(&self) -> EvaluatorPersona {
        EvaluatorPersona::Architect
    }
    async fn evaluate(&self, shift: &CognitiveShift) -> Result<bool, MimirError> {
        // DERIVATION: Architect approves if entropy change < 0.2 to maintain stability.
        match shift {
            CognitiveShift::ManifoldPropagation { entropy_change } => Ok(*entropy_change < 0.2),
            _ => Ok(true), // Other shifts are structurally neutral for this persona
        }
    }
}
