//! Map a `Size` to the koala-core gates that should run for it. The
//! mapping mirrors the spec table in
//! `wiki/features/adaptive-workflow.md`.

use crate::size::Size;

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct Gate {
    pub id: &'static str,
    /// One-line summary printed in the gate table.
    pub intent: &'static str,
    /// Whether failure blocks the PR at this size.
    pub blocking: bool,
}

const GATE_FMT_BUILD_TEST: Gate = Gate {
    id: "cargo.fmt+build+test",
    intent: "format check, workspace build, full test suite",
    blocking: true,
};

const GATE_INVARIANT: Gate = Gate {
    id: "koala.invariant",
    intent: "built-in invariant suite (arch / deps / health / governance)",
    blocking: true,
};

const GATE_DRIFT: Gate = Gate {
    id: "koala.drift",
    intent: "wiki ↔ code drift",
    blocking: true,
};

const GATE_ARTIFACT: Gate = Gate {
    id: "koala.artifact-required",
    intent: "≥1 reviewer artifact required (`.review/round-N/`)",
    blocking: true,
};

const GATE_FEATURE_SYNC: Gate = Gate {
    id: "koala.feature-sync",
    intent: "PR must update the matching `wiki/features/X.md`",
    blocking: true,
};

const GATE_ADR: Gate = Gate {
    id: "koala.adr",
    intent:
        "architectural change must be backed by an ADR (add/supersede, or cite an accepted one)",
    blocking: true,
};

pub fn gates_for(size: Size) -> Vec<Gate> {
    match size {
        Size::Small => vec![GATE_FMT_BUILD_TEST, GATE_INVARIANT, GATE_DRIFT],
        Size::Medium => vec![
            GATE_FMT_BUILD_TEST,
            GATE_INVARIANT,
            GATE_DRIFT,
            GATE_ARTIFACT,
        ],
        Size::Large => vec![
            GATE_FMT_BUILD_TEST,
            GATE_INVARIANT,
            GATE_DRIFT,
            GATE_ARTIFACT,
            GATE_FEATURE_SYNC,
        ],
        Size::Architectural => vec![
            GATE_FMT_BUILD_TEST,
            GATE_INVARIANT,
            GATE_DRIFT,
            GATE_ARTIFACT,
            GATE_FEATURE_SYNC,
            GATE_ADR,
        ],
    }
}

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

    #[test]
    fn small_runs_three_gates() {
        assert_eq!(gates_for(Size::Small).len(), 3);
    }

    #[test]
    fn architectural_runs_every_gate() {
        let g = gates_for(Size::Architectural);
        assert!(g.iter().any(|x| x.id == "koala.adr"));
        assert!(g.iter().any(|x| x.id == "koala.feature-sync"));
    }

    #[test]
    fn medium_requires_artifact_but_not_feature_sync() {
        let g = gates_for(Size::Medium);
        assert!(g.iter().any(|x| x.id == "koala.artifact-required"));
        assert!(!g.iter().any(|x| x.id == "koala.feature-sync"));
    }
}
