# Copyright (c) 2026 PULSE Contributors. Proprietary. All rights reserved.
# See LICENSE file for details.
"""Inline compliance gate — synchronous check before task + tool execution (Layer 11).

Two gates:
  1. check_task_compliance() — called at task claim time (title/description)
  2. check_tool_compliance() — called before EVERY tool dispatch (Sacred Boundary #1)
"""

from pulse.daemons.runtime.compliance_validator import HARM_PATTERNS, PII_PATTERNS
from pulse.core.trust_gate import IMMUTABLE_PATHS


def check_task_compliance(task: dict) -> tuple[bool, str]:
    """Check task title + description for harm/PII. Returns (passed, reason)."""
    title = task.get("title", "")
    # Memory tasks: only bypass if title is EXACTLY the tag (no trailing commands)
    if title.strip().startswith("[EXTRACT_KNOWLEDGE]") and "://" not in title:
        return True, ""
    if title.strip().startswith("[CLEAN_INTENTS]") and "://" not in title:
        return True, ""
    if task.get("domain") == "brain" and task.get("memory_data"):
        return True, ""
    text = f"{title} {task.get('description', '')}"
    for name, pattern in HARM_PATTERNS.items():
        if pattern.search(text):
            return False, f"HARM:{name}"
    for name, pattern in PII_PATTERNS.items():
        if pattern.search(text):
            return False, f"PII:{name}"
    return True, ""


def check_tool_compliance(tool_name: str, args: dict) -> tuple[bool, str]:
    """Pre-execution gate for every tool call. Returns (passed, reason).

    Checks:
      1. Immutable path protection (Sacred Boundary #7)
      2. Content scanning for harm patterns
      3. Command scanning for harm patterns
    """
    # 1. Block writes to safety-critical files
    if tool_name in ("write_file", "edit_file"):
        path = (args.get("path", "") or "").replace("\\", "/")
        for pattern in IMMUTABLE_PATHS:
            if pattern.search(path):
                return False, f"SACRED_BOUNDARY:immutable_path:{path}"
        # 2. Scan content for harm patterns
        content = (args.get("content", "") or "") + (args.get("new_text", "") or "")
        if content:
            for name, pattern in HARM_PATTERNS.items():
                if pattern.search(content):
                    return False, f"HARM:{name}:in_content"

    # 3. Scan commands for harm patterns
    if tool_name == "run_command":
        cmd = args.get("cmd", "") or args.get("command", "") or ""
        for name, pattern in HARM_PATTERNS.items():
            if pattern.search(cmd):
                return False, f"HARM:{name}:in_command"

    return True, ""
