#!/usr/bin/env python3
"""
Best Practice: Separation of Planning and Execution

Demonstrates the recommended production pattern:
- Use separate warrants for planning vs execution
- Apply trust levels for organizational boundaries
- Leverage attenuation for delegation

This demonstrates the recommended production pattern using Tenuo's current API.
"""

from tenuo import (
    SigningKey,
    Warrant,
    Pattern,
    guard,
    warrant_scope,
    key_scope,
)
from tenuo.exceptions import AuthorizationError


# ============================================================================
# Setup: Three-Tier Architecture
# ============================================================================

print("=" * 70)
print("Multi-Tier Delegation Pattern - Best Practice")
print("=" * 70)

# Tier 1: Control Plane (highest authority)
print("\n1. Setting up three-tier architecture:")
control_kp = SigningKey.generate()
print("   ✓ Control Plane (root authority)")

# Tier 2: Orchestrator (planning/coordination)
orchestrator_kp = SigningKey.generate()
print("   ✓ Orchestrator (planning/coordination)")

# Tier 3: Worker (execution)
worker_kp = SigningKey.generate()
print("   ✓ Worker (execution)")

# ============================================================================
# Step 1: Control Plane Issues Root Warrant to Orchestrator
# ============================================================================

print("\n" + "=" * 70)
print("STEP 1: Control Plane → Orchestrator (Root Warrant)")
print("=" * 70)

# Control plane issues broad warrant to orchestrator
root_warrant = (
    Warrant.mint_builder()
    .capability("file_operations", path=Pattern("/data/*"))  # Broad path access
    .holder(orchestrator_kp.public_key)
    .ttl(3600)
    .mint(control_kp)
)

print("\n✓ Issued root warrant to orchestrator")
print(f"  Tools: {root_warrant.tools}")
print(f"  Depth: {root_warrant.depth}")
print("  Constraints: path must match /data/*")
print("  TTL: 3600 seconds")
print("\n  ℹ️  Orchestrator has BROAD authority for planning")

# ============================================================================
# Step 2: Orchestrator Attenuates Warrant for Worker
# ============================================================================

print("\n" + "=" * 70)
print("STEP 2: Orchestrator → Worker (Attenuated Warrant)")
print("=" * 70)

# Orchestrator creates narrow warrant for specific task
worker_warrant = (
    root_warrant.grant_builder()
    .capability("file_operations", path=Pattern("/data/reports/*"))  # Narrower path
    .holder(worker_kp.public_key)
    .ttl(60)  # Much shorter TTL
    .grant(orchestrator_kp)  # orchestrator signs (they hold the parent warrant)
)

print("\n✓ Attenuated warrant for worker")
print(f"  Tools: {worker_warrant.tools}")
print(f"  Depth: {worker_warrant.depth}")
print("  Constraints: path must match /data/reports/* (narrower!)")
print("  TTL: 60 seconds (shorter!)")
print("\n  ✓  Worker has NARROW authority for execution")
print("  ✓  Capabilities SHRUNK during delegation")

# ============================================================================
# Step 3: Worker Executes with Attenuated Warrant
# ============================================================================

print("\n" + "=" * 70)
print("STEP 3: Worker Executes Tools")
print("=" * 70)


@guard(tool="file_operations")
def file_operations(path: str, operation: str = "read"):
    """A sensitive tool that requires authorization."""
    print(f"  [EXEC] {operation.capitalize()}ing file: {path}")
    return f"Contents of {path}"


print("\nTesting authorization with attenuated warrant:")

# Test 1: Allowed - within narrow constraints
print("\n  Test 1: path=/data/reports/q3.txt")
try:
    with warrant_scope(worker_warrant), key_scope(worker_kp):
        result = file_operations(path="/data/reports/q3.txt", operation="read")
        print(f"    ✓ ALLOWED: {result}")
except AuthorizationError as e:
    print(f"    ✗ BLOCKED: {e}")

# Test 2: Blocked - outside narrow constraints (but within root)
print("\n  Test 2: path=/data/secrets/passwords.txt")
try:
    with warrant_scope(worker_warrant), key_scope(worker_kp):
        result = file_operations(path="/data/secrets/passwords.txt", operation="read")
        print(f"    ✗ ALLOWED: {result} (UNEXPECTED!)")
except AuthorizationError:
    print("    ✓ BLOCKED: Outside /data/reports/* constraint")

# Test 3: Blocked - completely outside bounds
print("\n  Test 3: path=/etc/passwd")
try:
    with warrant_scope(worker_warrant), key_scope(worker_kp):
        result = file_operations(path="/etc/passwd", operation="read")
        print(f"    ✗ ALLOWED: {result} (UNEXPECTED!)")
except AuthorizationError:
    print("    ✓ BLOCKED: Outside /data/* bound")

# ============================================================================
# Step 4: Demonstrate Orchestrator's Broader Access
# ============================================================================

print("\n" + "=" * 70)
print("STEP 4: Orchestrator's Broader Access")
print("=" * 70)

print("\nOrchestrator can access paths worker cannot:")

# Orchestrator can access /data/secrets (within root constraints)
print("\n  Orchestrator accessing /data/secrets/config.json:")
try:
    with warrant_scope(root_warrant), key_scope(orchestrator_kp):
        result = file_operations(path="/data/secrets/config.json", operation="read")
        print(f"    ✓ ALLOWED: {result}")
        print("    ℹ️  Orchestrator has broader /data/* access")
except AuthorizationError as e:
    print(f"    ✗ BLOCKED: {e}")

# ============================================================================
# Key Takeaways
# ============================================================================

print("\n" + "=" * 70)
print("KEY TAKEAWAYS - Production Best Practices")
print("=" * 70)
print("""
1. SEPARATION OF CONCERNS
   - Orchestrator = planning with broad authority
   - Worker = execution with narrow authority
   - Prevents workers from exceeding task scope

2. MONOTONIC ATTENUATION
   - Capabilities ONLY shrink during delegation
   - Worker cannot access /data/secrets (only /data/reports)
   - TTL shortened from 3600s to 60s

3. CRYPTOGRAPHIC BINDING
   - Chain links cryptographically bind parent to child
   - Parent signs child's payload
   - Enables offline verification

4. RECOMMENDED PATTERN
   - Control Plane → broad warrant → Orchestrator
   - Orchestrator → narrow warrant → Worker
   - Worker executes with minimal, time-bound authority

5. SECURITY PROPERTIES
   - Proof-of-Possession prevents warrant theft
   - Attenuation prevents privilege escalation
   - Short TTLs limit blast radius
   - Offline verification (no phone home)
""")

print("=" * 70)
print("This is the RECOMMENDED pattern for production deployments!")
print("=" * 70)
