"""Aarvion Guard plugin for Hermes agents.

Registers a pre_tool_call hook that forwards every tool call to the local
guard PDP for governance evaluation. The guard's Go normalizer handles
surface classification and DLP scanning — the plugin just sends raw
tool name + args.
"""
from __future__ import annotations

import logging
from typing import Any

from . import guard_client

logger = logging.getLogger("aarvion.guard.hermes")

_config: guard_client.GuardConfig | None = None


def register(ctx: Any) -> None:
    """Called by Hermes on plugin load. Registers governance hooks."""
    global _config
    _config = guard_client.load_config()
    if not _config.get("enabled"):
        logger.info("Aarvion Guard not configured, governance disabled")
        return
    ctx.register_hook("pre_tool_call", on_tool_call)
    ctx.register_hook("pre_gateway_dispatch", on_inbound_message)
    logger.info("Aarvion Guard governance enabled")


def on_tool_call(
    tool_name: str,
    args: dict[str, Any],
    task_id: str = "",
    session_id: str = "",
    tool_call_id: str = "",
    turn_id: str = "",
    **kwargs: Any,
) -> dict[str, Any] | None:
    """pre_tool_call hook. Returns {"action": "block", ...} to deny, None to allow."""
    verdict = guard_client.evaluate(
        tool_name=tool_name,
        args=args if isinstance(args, dict) else {},
        config=_config,
        agent_id=task_id,
        session_id=session_id,
    )
    if verdict["verdict"] == "deny":
        reason = verdict.get("reason", "Policy denied this action")
        policy_id = verdict.get("policy_id", "")
        msg = "Blocked by governance policy"
        if reason:
            msg += f": {reason}"
        if policy_id:
            msg += f" [{policy_id}]"
        return {"action": "block", "message": msg}

    return None


def on_inbound_message(
    channel: str = "",
    sender: str = "",
    message: str = "",
    task_id: str = "",
    session_id: str = "",
    **kwargs: Any,
) -> dict[str, Any] | None:
    """pre_gateway_dispatch hook. Returns {"action": "skip", ...} to drop, None to allow."""
    verdict = guard_client.evaluate_inbound(
        channel=channel,
        sender=sender,
        message=message,
        config=_config,
        agent_id=task_id,
        session_id=session_id,
    )
    if verdict["verdict"] == "deny":
        reason = verdict.get("reason", "Inbound message blocked by channel policy")
        return {"action": "skip", "message": reason}

    return None
