#!/usr/bin/env python3
"""Agent for implementing and auditing Privileged Access Workstation (PAW) configurations."""

import json
import argparse
import subprocess
from datetime import datetime


def check_device_hardening():
    """Audit local device hardening controls for PAW compliance."""
    checks = {}
    hardening_cmds = {
        "credential_guard": ["powershell", "-Command",
            "(Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\\Microsoft\\Windows\\DeviceGuard).SecurityServicesRunning"],
        "vbs_status": ["powershell", "-Command",
            "(Get-CimInstance -ClassName Win32_DeviceGuard -Namespace root\\Microsoft\\Windows\\DeviceGuard).VirtualizationBasedSecurityStatus"],
        "secure_boot": ["powershell", "-Command", "Confirm-SecureBootUEFI"],
        "bitlocker": ["powershell", "-Command",
            "(Get-BitLockerVolume -MountPoint C:).ProtectionStatus"],
        "applocker_status": ["powershell", "-Command",
            "(Get-AppLockerPolicy -Effective -Xml | Select-String 'RuleCollection').Count"],
        "firewall_enabled": ["powershell", "-Command",
            "(Get-NetFirewallProfile | Where-Object {$_.Enabled -eq $true}).Name -join ','"],
        "uac_level": ["reg", "query",
            "HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System",
            "/v", "ConsentPromptBehaviorAdmin"],
    }
    for name, cmd in hardening_cmds.items():
        try:
            result = subprocess.run(cmd, capture_output=True, text=True, timeout=15)
            output = result.stdout.strip()
            checks[name] = {"value": output, "status": "PASS" if output and output not in ("0", "False", "") else "FAIL"}
        except Exception as e:
            checks[name] = {"value": str(e), "status": "ERROR"}
    passed = sum(1 for c in checks.values() if c["status"] == "PASS")
    return {
        "timestamp": datetime.utcnow().isoformat(),
        "checks": checks,
        "passed": passed,
        "total": len(checks),
        "compliance_pct": round(passed / len(checks) * 100, 1),
        "risk": "LOW" if passed >= 6 else "MEDIUM" if passed >= 4 else "HIGH",
    }


def check_local_admin_group():
    """Enumerate local Administrators group membership for JIT audit."""
    try:
        result = subprocess.run(
            ["powershell", "-Command",
             "Get-LocalGroupMember -Group Administrators | Select-Object Name,ObjectClass,PrincipalSource | ConvertTo-Json"],
            capture_output=True, text=True, timeout=15)
        members = json.loads(result.stdout) if result.stdout.strip() else []
        if isinstance(members, dict):
            members = [members]
        expected_admins = ["Administrator", "Domain Admins"]
        unexpected = [m for m in members if not any(e in m.get("Name", "") for e in expected_admins)]
        return {
            "total_members": len(members),
            "members": members,
            "unexpected_admins": unexpected,
            "jit_finding": "UNEXPECTED_ADMINS" if unexpected else "CLEAN",
            "severity": "HIGH" if unexpected else "INFO",
        }
    except Exception as e:
        return {"error": str(e)}


def check_installed_software():
    """Audit installed software against PAW allowlist."""
    try:
        result = subprocess.run(
            ["powershell", "-Command",
             "Get-ItemProperty HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | "
             "Select-Object DisplayName,Publisher,InstallDate | Where-Object {$_.DisplayName -ne $null} | "
             "ConvertTo-Json -Depth 2"],
            capture_output=True, text=True, timeout=30)
        software = json.loads(result.stdout) if result.stdout.strip() else []
        if isinstance(software, dict):
            software = [software]
        blocked_patterns = [
            "chrome", "firefox", "spotify", "steam", "vlc", "zoom", "slack",
            "dropbox", "onedrive personal", "itunes", "whatsapp", "telegram",
        ]
        violations = []
        for sw in software:
            name = (sw.get("DisplayName") or "").lower()
            if any(p in name for p in blocked_patterns):
                violations.append({"name": sw.get("DisplayName"), "publisher": sw.get("Publisher")})
        return {
            "total_installed": len(software),
            "paw_violations": len(violations),
            "violations": violations[:20],
            "finding": "BLOCKED_SOFTWARE_FOUND" if violations else "COMPLIANT",
        }
    except Exception as e:
        return {"error": str(e)}


def check_network_restrictions():
    """Verify PAW network isolation and restrictions."""
    checks = {}
    try:
        result = subprocess.run(
            ["powershell", "-Command",
             "Get-NetFirewallRule | Where-Object {$_.Enabled -eq 'True' -and $_.Direction -eq 'Outbound' -and $_.Action -eq 'Block'} | "
             "Measure-Object | Select-Object -ExpandProperty Count"],
            capture_output=True, text=True, timeout=15)
        checks["outbound_block_rules"] = int(result.stdout.strip() or 0)
    except Exception:
        checks["outbound_block_rules"] = 0
    try:
        result = subprocess.run(["powershell", "-Command",
            "Test-NetConnection -ComputerName google.com -Port 80 -WarningAction SilentlyContinue | Select-Object TcpTestSucceeded | ConvertTo-Json"],
            capture_output=True, text=True, timeout=15)
        data = json.loads(result.stdout) if result.stdout.strip() else {}
        checks["internet_access"] = data.get("TcpTestSucceeded", True)
    except Exception:
        checks["internet_access"] = "unknown"
    paw_should_block_internet = checks.get("internet_access") is False
    return {
        "network_checks": checks,
        "internet_blocked": paw_should_block_internet,
        "finding": "INTERNET_BLOCKED" if paw_should_block_internet else "INTERNET_ALLOWED",
        "severity": "INFO" if paw_should_block_internet else "MEDIUM",
        "recommendation": "PAW Tier 0 should block general internet — restrict to management endpoints only",
    }


def full_paw_audit():
    """Run comprehensive PAW compliance audit."""
    return {
        "audit_type": "Privileged Access Workstation",
        "timestamp": datetime.utcnow().isoformat(),
        "device_hardening": check_device_hardening(),
        "admin_group": check_local_admin_group(),
        "software_compliance": check_installed_software(),
        "network_isolation": check_network_restrictions(),
    }


def main():
    parser = argparse.ArgumentParser(description="Privileged Access Workstation Audit Agent")
    sub = parser.add_subparsers(dest="command")
    sub.add_parser("harden", help="Check device hardening controls")
    sub.add_parser("admins", help="Audit local admin group membership")
    sub.add_parser("software", help="Check installed software against allowlist")
    sub.add_parser("network", help="Verify network isolation")
    sub.add_parser("full", help="Full PAW compliance audit")
    args = parser.parse_args()
    if args.command == "harden":
        result = check_device_hardening()
    elif args.command == "admins":
        result = check_local_admin_group()
    elif args.command == "software":
        result = check_installed_software()
    elif args.command == "network":
        result = check_network_restrictions()
    elif args.command == "full":
        result = full_paw_audit()
    else:
        parser.print_help()
        return
    print(json.dumps(result, indent=2, default=str))


if __name__ == "__main__":
    main()
