#!/usr/bin/env python3
"""
Example: Applying L3-L5 Security Hooks to a Claude Code Agent.

This script shows how to configure and test each security level
from the Security Foundation skill kit.

Usage:
    python example-security-hooks.py  --level 3   # Test L3 blacklist
    python example-security-hooks.py  --level 4   # Test L4 whitelist
    python example-security-hooks.py  --level 5   # Test L5 no-bash
"""

import argparse
import sys


# ── L3: Blacklist Hook ────────────────────────────────────────────

BLOCKED_PATTERNS = [
    r"rm\s+-rf",
    r"git\s+clean\s+-fdx",
    r"DROP\s+(TABLE|DATABASE)",
    r"truncate\s+",
    r"curl\s+-X\s+POST",
]

def l3_check(command: str) -> tuple[bool, str]:
    """Check command against blacklist. Returns (blocked, reason)."""
    import re
    for pattern in BLOCKED_PATTERNS:
        if re.search(pattern, command, re.IGNORECASE):
            return True, pattern
    return False, ""


# ── L4: Whitelist Hook ────────────────────────────────────────────

ALLOWED_COMMANDS = [
    r"^npm test$",
    r"^git status$",
    r"^uv run pytest",
    r"^cat [\w/\.-]+$",
    r"^pwd$",
    r"^ls\b",
]

def l4_check(command: str) -> bool:
    """Check command against whitelist. Returns True if allowed."""
    import re
    return any(re.match(p, command) for p in ALLOWED_COMMANDS)


# ── L5: No Bash (Tool-based only) ─────────────────────────────────

def l5_execute(tool_name: str, params: dict) -> str:
    """Execute only through approved tools. No bash at all."""
    allowed_tools = {
        "read_file": lambda p: f"Reading file: {p['path']}",
        "write_file": lambda p: f"Writing {len(p['content'])} chars to {p['path']}",
        "grep_search": lambda p: f"Searching for '{p['pattern']}' in {p.get('path', '.')}",
    }
    if tool_name not in allowed_tools:
        return f"BLOCKED: {tool_name} is not allowed at L5"
    return allowed_tools[tool_name](params)


# ── Test Harness ──────────────────────────────────────────────────

def test_blacklist():
    print("  L3 Blacklist Tests:")
    tests = [
        ("rm -rf /", True),
        ("git status", False),
        ("DROP TABLE users", True),
        ("npm install express", False),
        ("git clean -fdx", True),
        ("pwd", False),
    ]
    for cmd, expected in tests:
        blocked, reason = l3_check(cmd)
        status = "⛔ blocked" if blocked else "✓ allowed"
        assert blocked == expected, f"FAIL: {cmd}"
        print(f"    {status} → {cmd}")


def test_whitelist():
    print("  L4 Whitelist Tests:")
    tests = [
        ("npm test", True),
        ("python cleanup.py", False),
        ("git status", True),
        ("rm -rf node_modules", False),
        ("cat config.json", True),
    ]
    for cmd, expected in tests:
        allowed = l4_check(cmd)
        status = "✓ allowed" if allowed else "⛔ blocked"
        assert allowed == expected, f"FAIL: {cmd}"
        print(f"    {status} → {cmd}")


def test_nobash():
    print("  L5 No-Bash Tests:")
    tests = [
        ("read_file", {"path": "test.txt"}, True),
        ("delete_file", {"path": "test.txt"}, False),
        ("write_file", {"path": "out.txt", "content": "hi"}, True),
    ]
    for tool, params, expected in tests:
        result = l5_execute(tool, params)
        is_allowed = not result.startswith("BLOCKED")
        status = "✓ allowed" if is_allowed else "⛔ blocked"
        assert is_allowed == expected, f"FAIL: {tool}"
        print(f"    {status} → {tool}")


if __name__ == "__main__":
    parser = argparse.ArgumentParser()
    parser.add_argument("--level", type=int, choices=[3, 4, 5], default=3)
    args = parser.parse_args()

    print(f"\nSecurity Foundation — Testing L{args.level}\n")

    if args.level == 3:
        test_blacklist()
    elif args.level == 4:
        test_whitelist()
    elif args.level == 5:
        test_nobash()

    print("\n  All tests passed.\n")
