"""DoctorService — cluster health diagnostics.

Delegates to the check registry (sdk/checks.py) for all checks and fixes.
Used by both ``clusters:doctor`` and ``clusters:setup``.
"""

from __future__ import annotations

from collections.abc import Callable
from typing import TYPE_CHECKING

from kuberoku.models import CheckResult, FixResult, RbacFixYaml, RbacReport
from kuberoku.sdk.checks import CLUSTER_REQUIREMENTS, fix_all
from kuberoku.sdk.rbac import check_rbac, generate_rbac_yaml

if TYPE_CHECKING:
    from kuberoku.factory import KuberokuFactory


class DoctorService:
    """Runs cluster diagnostic checks via the check registry."""

    def __init__(self, factory: KuberokuFactory) -> None:
        self._factory = factory

    def run_checks(
        self,
        on_step: Callable[[str], None] | None = None,
    ) -> tuple[CheckResult, ...]:
        """Run all diagnostic checks and return results."""
        results: list[CheckResult] = []
        k8s = self._factory.k8s
        ns = self._factory.namespace
        prefix = self._factory.prefix
        domain = self._factory.domain

        for req in CLUSTER_REQUIREMENTS:
            if on_step:
                on_step(f"Checking {req.description}...")
            result = req.check_fn(k8s, ns, prefix, domain)
            results.append(result)

        return tuple(results)

    def fix_all(
        self,
        on_step: Callable[[str], None] | None = None,
    ) -> tuple[FixResult, ...]:
        """Attempt to fix all fixable failed checks."""
        if on_step:
            on_step("Running auto-fix...")
        return fix_all(self._factory)

    def check_rbac_permissions(
        self,
        on_step: Callable[[str], None] | None = None,
    ) -> RbacReport:
        """Check all RBAC permissions via SelfSubjectAccessReview."""
        if on_step:
            on_step("Checking RBAC permissions...")
        return check_rbac(self._factory.k8s, self._factory.namespace)

    def generate_rbac_fix(
        self,
        on_step: Callable[[str], None] | None = None,
    ) -> RbacFixYaml:
        """Generate Role + RoleBinding YAML for missing permissions."""
        if on_step:
            on_step("Generating RBAC fix YAML...")
        report = self.check_rbac_permissions()
        return generate_rbac_yaml(report, self._factory.namespace)

    def run(
        self,
        on_step: Callable[[str], None] | None = None,
    ) -> tuple[CheckResult, ...]:
        """Backward-compatible alias for run_checks()."""
        return self.run_checks(on_step=on_step)
