"""KarmaDue pre-action guard for LangChain / LangGraph tools (no account needed).

Get it:  curl -O https://karmadue.expo.app/recipes/karmadue_langchain.py
Docs:    https://karmadue.expo.app/docs/langchain.md
Only dependency: langchain-core (HTTP uses the standard library).
"""
import functools, json, os, urllib.request
from langchain_core.tools import tool

KD_PREFLIGHT = "https://ogogoizwsfaduzehkshb.supabase.co/functions/v1/public-api/v1/preflight"
KD_VIA = os.environ.get("KARMADUE_VIA", "recipe-langchain")

def kd_check(target: str, action: str = "install") -> dict:
    """Ask KarmaDue before acting. target: 'npm:name@ver', 'pypi:name==ver', or a URL."""
    req = urllib.request.Request(KD_PREFLIGHT, data=json.dumps({"target": target, "action": action}).encode(),
                                 headers={"content-type": "application/json", "x-kd-via": KD_VIA})
    try:
        with urllib.request.urlopen(req, timeout=15) as r:
            body = json.load(r)
        return {**(body.get("data") or {}), "request_id": body.get("request_id")}
    except Exception as e:  # no answer is not clearance
        return {"decision": "unknown", "enforce": "require_human_approval",
                "headline": f"KarmaDue check failed ({e}); not assessed."}

class KarmaDueBlocked(Exception):
    pass

def guarded(target_from_args, action="install", block_on_warn=True):
    """Decorator: run a KarmaDue check before the tool body. Obeys data.enforce; decision "unknown" asks.
    For tools that start or connect MCP servers or run scripts, pass action="run"."""
    def wrap(fn):
        @functools.wraps(fn)
        def inner(*args, **kwargs):
            d = kd_check(target_from_args(*args, **kwargs), action)
            enforce = d.get("enforce")
            ref = d.get("receipt_id") or d.get("request_id") or ""
            if enforce == "block":
                return f"BLOCKED by KarmaDue: {d.get('headline')} [{ref}] Do not retry; tell your person."
            # "unknown" means KarmaDue had no evidence. Treat it as "ask your person" even when enforce says
            # proceed_with_care (seen 2026-11-12 for local scripts and unlisted MCP URLs with action "connect").
            if block_on_warn and (enforce != "proceed_with_care" or d.get("decision") == "unknown"):
                return f"NEEDS APPROVAL (KarmaDue): {d.get('headline')} [{ref}] Ask your person before retrying."
            note = "" if enforce == "proceed_with_care" and d.get("decision") != "unknown" else f"KarmaDue: {d.get('headline')} [{ref}]\n"
            return note + fn(*args, **kwargs)
        return inner
    return wrap

@tool
@guarded(lambda package, ecosystem="pypi": f"pypi:{package}" if ecosystem == "pypi" else f"npm:{package}")
def install_package(package: str, ecosystem: str = "pypi") -> str:
    """Install a package. package: 'requests==2.33.0' (pypi) or 'left-pad@1.3.0' (npm)."""
    # Replace with your real installer (subprocess.run([...])). Kept as a dry run here.
    return f"(dry run) would install {ecosystem}:{package}"
