#!/usr/bin/env python3
"""
Workflow Builder - macOS Automation Templates
Safe, auditable workflow automation
"""

import json
import os
import sys
import subprocess
from datetime import datetime


TEMPLATES = {
    "email-organization": {
        "name": "Email Organization",
        "description": "Organize emails from specified folder into categories",
        "steps": [
            {"action": "scan", "target": "~/Downloads", "pattern": "*.eml"},
            {"action": "categorize", "by": "sender"},
            {"action": "move", "use": "trash_instead_of_rm"}
        ]
    },
    "file-processing": {
        "name": "File Processing Pipeline",
        "description": "Convert and organize files in batch",
        "steps": [
            {"action": "list_files", "from": "input_folder"},
            {"action": "validate", "safety": "dry_run_first"},
            {"action": "process"},
            {"action": "archive_originals"}
        ]
    },
    "backup-sync": {
        "name": "Backup & Sync",
        "description": "Safe backup workflow with audit trail",
        "steps": [
            {"action": "enumerate_sources"},
            {"action": "validate_destination"},
            {"action": "dry_run"},
            {"action": "execute_with_logging"},
            {"action": "verify"}
        ]
    }
}


def load_template(name: str) -> dict:
    """Load a workflow template"""
    return TEMPLATES.get(name, {})


def validate_workflow(workflow: dict) -> tuple[bool, str]:
    """
    Validate a workflow for safety
    
    Returns:
        (is_safe, message)
    """
    required_fields = ["name", "steps"]
    
    for field in required_fields:
        if field not in workflow:
            return False, f"Missing required field: {field}"
    
    # Check for dangerous patterns
    for step in workflow.get("steps", []):
        if isinstance(step, dict):
            action = step.get("action", "").lower()
            
            # Flag destructive operations
            if action in ["delete", "remove"] and step.get("use") != "trash_instead_of_rm":
                return False, f"Destructive action '{action}' must use trash, not rm"
            
            # Flag unrestricted operations
            if action in ["execute", "shell"] and not step.get("audit"):
                return False, f"Action '{action}' requires audit logging"
    
    return True, "Workflow validated"


def create_workflow(name: str, template: str = None, params: dict = None) -> dict:
    """
    Create a new workflow
    
    Args:
        name: Workflow name
        template: Template to base on
        params: Custom parameters
    
    Returns:
        Workflow definition
    """
    params = params or {}
    
    if template:
        base = load_template(template)
        workflow = {
            "name": name,
            "template": template,
            "created": datetime.now().isoformat(),
            "steps": base.get("steps", []),
            "params": params,
            "dry_run": True,
            "audit_log": []
        }
    else:
        workflow = {
            "name": name,
            "created": datetime.now().isoformat(),
            "steps": [],
            "params": params,
            "dry_run": True,
            "audit_log": []
        }
    
    # Validate before returning
    is_safe, msg = validate_workflow(workflow)
    workflow["validation"] = {"safe": is_safe, "message": msg}
    
    return workflow


def execute_workflow(workflow: dict, dry_run: bool = True) -> dict:
    """
    Execute a workflow with full audit logging
    
    Args:
        workflow: Workflow definition
        dry_run: If True, simulate without actual changes
    
    Returns:
        Execution result with audit trail
    """
    is_safe, validation_msg = validate_workflow(workflow)
    
    if not is_safe:
        return {
            "success": False,
            "error": validation_msg,
            "executed": False
        }
    
    result = {
        "workflow": workflow["name"],
        "executed": not dry_run,
        "dry_run": dry_run,
        "timestamp": datetime.now().isoformat(),
        "steps_completed": 0,
        "steps_total": len(workflow.get("steps", [])),
        "audit_trail": []
    }
    
    for i, step in enumerate(workflow.get("steps", [])):
        log_entry = {
            "step": i + 1,
            "action": step.get("action"),
            "status": "simulated" if dry_run else "completed",
            "timestamp": datetime.now().isoformat()
        }
        result["audit_trail"].append(log_entry)
        result["steps_completed"] += 1
    
    result["success"] = True
    return result


def main():
    if len(sys.argv) < 2:
        print("Workflow Builder - macOS Automation")
        print("Usage: workflow-builder <action> [args]")
        print("\nActions:")
        print("  list              - List available templates")
        print("  create <name>     - Create new workflow")
        print("  validate <file>   - Validate workflow file")
        return
    
    action = sys.argv[1]
    
    if action == "list":
        print("Available templates:\n")
        for key, template in TEMPLATES.items():
            print(f"  {key:20} - {template['name']}")
    
    elif action == "create" and len(sys.argv) > 2:
        name = sys.argv[2]
        template = sys.argv[3] if len(sys.argv) > 3 else None
        
        workflow = create_workflow(name, template)
        print(json.dumps(workflow, indent=2))
    
    elif action == "validate" and len(sys.argv) > 2:
        filepath = sys.argv[2]
        if os.path.exists(filepath):
            with open(filepath, "r") as f:
                workflow = json.load(f)
            is_safe, msg = validate_workflow(workflow)
            print(f"Validation: {'✅ SAFE' if is_safe else '❌ UNSAFE'}")
            print(f"Message: {msg}")
        else:
            print(f"File not found: {filepath}")
    
    else:
        print("Unknown action or missing arguments")


if __name__ == "__main__":
    main()
