//! Scope configuration for aphoria.toml.
//!
//! Allows projects to declare their position in the organization hierarchy.

use serde::Deserialize;

/// Scope configuration in aphoria.toml.
///
/// # Example
///
/// ```toml
/// [scope]
/// project = "api-gateway"
/// team = "platform-team"
/// organization = "acme-corp"
/// ```
///
/// All fields are optional. When not specified:
/// - `project` defaults to the directory name or git repo name
/// - `team` and `organization` are considered unset (no inheritance)
#[derive(Debug, Clone, Default, Deserialize)]
#[serde(default)]
pub struct ScopeConfig {
    /// The project name.
    ///
    /// If not set, auto-detected from the project directory or git remote.
    pub project: Option<String>,

    /// The team this project belongs to.
    ///
    /// Used for team-level pattern inheritance.
    pub team: Option<String>,

    /// The organization this project belongs to.
    ///
    /// Used for organization-wide pattern inheritance.
    pub organization: Option<String>,
}

impl ScopeConfig {
    /// Create a new scope config with all levels set.
    pub fn new(
        project: Option<String>,
        team: Option<String>,
        organization: Option<String>,
    ) -> Self {
        Self { project, team, organization }
    }

    /// Convert to a ScopeContext for resolution.
    pub fn to_context(&self) -> super::ScopeContext {
        super::ScopeContext::new(self.project.clone(), self.team.clone(), self.organization.clone())
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_scope_config_default() {
        let config = ScopeConfig::default();
        assert!(config.project.is_none());
        assert!(config.team.is_none());
        assert!(config.organization.is_none());
    }

    #[test]
    fn test_scope_config_deserialize() {
        let toml = r#"
            project = "my-project"
            team = "my-team"
            organization = "my-org"
        "#;

        let config: ScopeConfig = toml::from_str(toml).expect("deserialize");
        assert_eq!(config.project, Some("my-project".to_string()));
        assert_eq!(config.team, Some("my-team".to_string()));
        assert_eq!(config.organization, Some("my-org".to_string()));
    }

    #[test]
    fn test_scope_config_partial_deserialize() {
        let toml = r#"
            project = "only-project"
        "#;

        let config: ScopeConfig = toml::from_str(toml).expect("deserialize");
        assert_eq!(config.project, Some("only-project".to_string()));
        assert!(config.team.is_none());
        assert!(config.organization.is_none());
    }

    #[test]
    fn test_to_context() {
        let config = ScopeConfig::new(
            Some("proj".to_string()),
            Some("team".to_string()),
            Some("org".to_string()),
        );

        let ctx = config.to_context();
        assert_eq!(ctx.project, Some("proj".to_string()));
        assert_eq!(ctx.team, Some("team".to_string()));
        assert_eq!(ctx.organization, Some("org".to_string()));
    }
}
