"""Policy engine — orchestrate all policy checks."""

from __future__ import annotations

from pathlib import Path

from nestdx.config.schema import NestConfig
from nestdx.policy.filesystem import FilesystemChecker
from nestdx.policy.secrets import SecretsScanner
from nestdx.session.models import FileChange, PolicyViolation


class PolicyEngine:
    """Run all policy checks against session data."""

    def __init__(self, config: NestConfig, project_root: Path | None = None):
        self.config = config
        self._secrets_scanner = SecretsScanner(
            config.policies.secrets, project_root=project_root
        )
        self._filesystem_checker = FilesystemChecker(config.policies.filesystem)

    def check_post_session(
        self, file_changes: list[FileChange], project_root: Path
    ) -> list[PolicyViolation]:
        """Run all post-session policy checks.

        Returns aggregated list of violations from all checkers.
        """
        violations: list[PolicyViolation] = []

        # Filesystem policy checks
        violations.extend(self._filesystem_checker.check(file_changes))

        # Secrets scanning on changed files
        violations.extend(self._secrets_scanner.scan_changes(file_changes, project_root))

        return violations

    def check_pre_run(self, tool_name: str) -> PolicyViolation | None:
        """Validate that a tool is enabled before running.

        Returns a violation if the tool is disabled, None if OK.
        """
        tool_config = self.config.tools.get(tool_name)
        if tool_config is None:
            return None  # Unknown tools are allowed in CRAWL

        if not tool_config.enabled:
            reason = f" ({tool_config.reason})" if tool_config.reason else ""
            return PolicyViolation(
                rule="tools.enabled",
                severity="error",
                message=f"Tool '{tool_name}' is disabled{reason}",
            )

        return None

    def check_network_policy(self, *, container_mode: bool) -> PolicyViolation | None:
        """Validate network policy configuration.

        Returns a warning if network policy is configured but won't be enforced
        (i.e., running in local mode).
        """
        network = self.config.policies.network
        if not network.block_all_other_egress:
            return None

        if not container_mode:
            return PolicyViolation(
                rule="network.egress",
                severity="warning",
                message=(
                    "Network egress control is configured but requires container mode. "
                    "Use `nestdx start --container` or add an `environment:` block."
                ),
            )

        return None
