//! Governance configuration types.
//!
//! Configuration for approval workflows and governance settings.

use std::path::PathBuf;

use serde::Deserialize;

use crate::governance::ApprovalWorkflow;

/// Governance workflow configuration.
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(default)]
pub struct GovernanceConfig {
    /// Whether governance is enabled.
    ///
    /// When false, pattern promotion proceeds without approval workflows.
    pub enabled: bool,

    /// Custom governance data directory.
    ///
    /// Defaults to `~/.aphoria/governance/`.
    pub governance_dir: Option<PathBuf>,

    /// Name of the default workflow to use.
    ///
    /// Must match a workflow in the `workflows` list.
    pub default_workflow: Option<String>,

    /// Configured approval workflows.
    #[serde(default)]
    pub workflows: Vec<ApprovalWorkflow>,

    /// Check for expired requests on every access.
    ///
    /// When true, timeout checks run automatically during list operations.
    /// When false, timeouts are only processed via explicit `governance check` command.
    #[serde(default)]
    pub check_timeouts_on_access: bool,
}

impl GovernanceConfig {
    /// Create a new governance config with a single workflow.
    pub fn with_workflow(workflow: ApprovalWorkflow) -> Self {
        Self {
            enabled: true,
            governance_dir: None,
            default_workflow: Some(workflow.name.clone()),
            workflows: vec![workflow],
            check_timeouts_on_access: false,
        }
    }

    /// Get a workflow by name.
    pub fn get_workflow(&self, name: &str) -> Option<&ApprovalWorkflow> {
        self.workflows.iter().find(|w| w.name == name)
    }

    /// Get the default workflow.
    pub fn get_default_workflow(&self) -> Option<&ApprovalWorkflow> {
        self.default_workflow.as_ref().and_then(|name| self.get_workflow(name))
    }

    /// Validate the configuration.
    pub fn validate(&self) -> Result<(), String> {
        if self.enabled && self.workflows.is_empty() {
            return Err("Governance is enabled but no workflows are configured".to_string());
        }

        if let Some(ref default) = self.default_workflow {
            if self.get_workflow(default).is_none() {
                return Err(format!("Default workflow '{}' not found", default));
            }
        }

        // Validate each workflow
        for workflow in &self.workflows {
            workflow.validate()?;
        }

        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::governance::workflow::{ApprovalStage, ApprovalWorkflow};

    #[test]
    fn test_default_config() {
        let config = GovernanceConfig::default();
        assert!(!config.enabled);
        assert!(config.workflows.is_empty());
    }

    #[test]
    fn test_with_workflow() {
        let workflow =
            ApprovalWorkflow::new("test", "Test").add_stage(ApprovalStage::new("s1", "Stage 1"));

        let config = GovernanceConfig::with_workflow(workflow);
        assert!(config.enabled);
        assert_eq!(config.default_workflow, Some("test".to_string()));
        assert_eq!(config.workflows.len(), 1);
    }

    #[test]
    fn test_get_workflow() {
        let workflow =
            ApprovalWorkflow::new("test", "Test").add_stage(ApprovalStage::new("s1", "Stage 1"));

        let config = GovernanceConfig::with_workflow(workflow);

        assert!(config.get_workflow("test").is_some());
        assert!(config.get_workflow("nonexistent").is_none());
    }

    #[test]
    fn test_validation() {
        // Enabled with no workflows - should fail
        let config = GovernanceConfig { enabled: true, ..Default::default() };
        assert!(config.validate().is_err());

        // Enabled with workflows - should pass
        let workflow =
            ApprovalWorkflow::new("test", "Test").add_stage(ApprovalStage::new("s1", "Stage 1"));
        let config = GovernanceConfig::with_workflow(workflow);
        assert!(config.validate().is_ok());

        // Invalid default workflow - should fail
        let config = GovernanceConfig {
            enabled: true,
            default_workflow: Some("nonexistent".to_string()),
            workflows: vec![
                ApprovalWorkflow::new("other", "Other").add_stage(ApprovalStage::new("s1", "S1"))
            ],
            ..Default::default()
        };
        assert!(config.validate().is_err());
    }

    #[test]
    fn test_serde_defaults() {
        let toml = r#"
enabled = true
default_workflow = "standard"
"#;

        let config: GovernanceConfig = toml::from_str(toml).expect("parse");
        assert!(config.enabled);
        assert_eq!(config.default_workflow, Some("standard".to_string()));
        assert!(config.workflows.is_empty()); // Default to empty
    }
}
