//! Allowlist-based gate. Denies any tool not on the list.

use super::trait_::{Gate, GateDecision, GateRequest};
use async_trait::async_trait;
use std::collections::HashSet;

/// Permits tools whose name appears in the allowlist; denies all others.
pub struct AllowlistGate {
    names: HashSet<String>,
}

impl AllowlistGate {
    /// Build from a slice of `&str`.
    #[must_use]
    pub fn new(names: &[&str]) -> Self {
        Self {
            names: names.iter().map(|s| (*s).to_string()).collect(),
        }
    }
}

#[async_trait]
impl Gate for AllowlistGate {
    async fn evaluate(&self, req: GateRequest) -> GateDecision {
        if self.names.contains(&req.tool_name) {
            GateDecision::Allow
        } else {
            GateDecision::Deny {
                code: "allowlist.miss".into(),
                reason: format!("tool `{}` not in allowlist", req.tool_name),
            }
        }
    }

    fn name(&self) -> &'static str {
        "AllowlistGate"
    }
}
