"""autogovern.py — minimal Python SDK for the AutoGovern Control Plane.

No dependencies — uses only the standard library (urllib).
Docs: https://autogovern.io/governance-api

Get a free API key: create an account at https://autogovern.io/account,
register an asset of kind "agent" or "mcp_server" in AI Inventory, then
click "Activate for Control Plane".
"""
import json
import urllib.error
import urllib.request


class AutoGovernError(Exception):
    def __init__(self, message, result=None):
        super().__init__(message)
        self.result = result


class AutoGovernClient:
    def __init__(self, api_key, base_url="https://autogovern.io"):
        if not api_key:
            raise ValueError("AutoGovernClient requires api_key — activate one at https://autogovern.io/account.")
        self.api_key = api_key
        self.base_url = base_url.rstrip("/")

    def evaluate(self, action, assessment_id=None):
        """Evaluate a single agent action against the Control Plane.

        action: dict with keys tool, action_type, target (optional),
            payload (optional), reversible (optional), sensitivity
            (optional), records_affected (optional). Any "agent" key you
            include is ignored — your key's registered identity is always
            authoritative, so it can't be spoofed from here.

        Returns the full decision dict: decision ("allow"|"review"|"deny"),
        riskScore, riskBand, matchedControls, matchedPolicies, reasons,
        ledger, agentIdentity, ...
        """
        body = json.dumps({"action": action, "assessment_id": assessment_id}).encode("utf-8")
        req = urllib.request.Request(
            f"{self.base_url}/api/control-plane/evaluate",
            data=body,
            method="POST",
            headers={
                "Content-Type": "application/json",
                "Authorization": f"Bearer {self.api_key}",
            },
        )
        try:
            with urllib.request.urlopen(req) as resp:
                return json.loads(resp.read().decode("utf-8"))
        except urllib.error.HTTPError as e:
            raw = e.read().decode("utf-8")
            try:
                payload = json.loads(raw) if raw else {}
            except json.JSONDecodeError:
                payload = {}
            raise AutoGovernError(payload.get("error", f"AutoGovern evaluate failed (HTTP {e.code})"), payload) from None

    def assert_allowed(self, action, assessment_id=None):
        """Raises AutoGovernError unless the decision is 'allow'; otherwise
        returns the result, same shape as evaluate()."""
        result = self.evaluate(action, assessment_id)
        if result.get("decision") != "allow":
            reasons = "; ".join(result.get("reasons") or [])
            raise AutoGovernError(f"Action was {result.get('decision')}: {reasons}", result)
        return result
