#!/usr/bin/env python3
"""
Maintenance Flow Seed Script for ResolutionFlow.

Creates sample maintenance flows (scheduled multi-target tasks) for common MSP
infrastructure maintenance work.

Run from the backend directory with:
  python -m scripts.seed_maintenance_flows --email admin@resolutionflow.example.com --password TestPass123!

Requirements:
- Backend server must be running (uvicorn app.main:app)
"""

import asyncio
import argparse
import httpx
from typing import Any


# API Configuration
API_BASE_URL = "http://localhost:8000/api/v1"

ADMIN_EMAIL = None
ADMIN_PASSWORD = None


# =============================================================================
# MAINTENANCE FLOW DEFINITIONS
# =============================================================================

def get_sonicwall_firmware_flow() -> dict[str, Any]:
    """SonicWall Firewall Firmware Update — check and install latest firmware."""
    return {
        "name": "SonicWall Firmware Update",
        "description": "Check for and install the latest firmware on SonicWall firewalls. Includes pre-flight backup, compatibility check, staged install, and post-update verification. Designed for batch execution across multiple client firewalls.",
        "tree_type": "maintenance",
        "tags": ["sonicwall", "firmware", "firewall", "maintenance", "security"],
        "intake_form": [
            {
                "variable_name": "firewall_ip",
                "label": "Firewall Management IP",
                "field_type": "ip_address",
                "required": True,
                "placeholder": "e.g. 192.168.1.1",
                "help_text": "Management IP or FQDN of the SonicWall appliance",
                "group_name": "Firewall Details",
                "display_order": 1,
            },
            {
                "variable_name": "firewall_model",
                "label": "SonicWall Model",
                "field_type": "select",
                "required": True,
                "options": [
                    "TZ270 / TZ270W",
                    "TZ370 / TZ370W",
                    "TZ470 / TZ470W",
                    "TZ570 / TZ570W",
                    "TZ670",
                    "NSa 2700",
                    "NSa 3700",
                    "NSa 4700",
                    "NSa 5700",
                    "NSa 6700",
                    "NSsp 10700 / 11700 / 13700",
                    "NSv (Virtual)",
                    "Other / Legacy",
                ],
                "group_name": "Firewall Details",
                "display_order": 2,
            },
            {
                "variable_name": "current_firmware",
                "label": "Current Firmware Version",
                "field_type": "text",
                "required": False,
                "placeholder": "e.g. 7.0.1-5145",
                "help_text": "Check under System > Status in the SonicWall UI",
                "group_name": "Firewall Details",
                "display_order": 3,
            },
            {
                "variable_name": "maintenance_window",
                "label": "Maintenance Window",
                "field_type": "text",
                "required": True,
                "placeholder": "e.g. Sat 10pm-2am EST",
                "help_text": "Approved maintenance window for this client",
                "group_name": "Scheduling",
                "display_order": 4,
            },
            {
                "variable_name": "client_name",
                "label": "Client Name",
                "field_type": "text",
                "required": True,
                "placeholder": "e.g. Contoso Ltd",
                "group_name": "Scheduling",
                "display_order": 5,
            },
            {
                "variable_name": "ticket_number",
                "label": "Ticket Number",
                "field_type": "text",
                "required": False,
                "placeholder": "e.g. TKT-2024-1234",
                "group_name": "Scheduling",
                "display_order": 6,
            },
        ],
        "tree_structure": {
            "steps": [
                {
                    "id": "step_1",
                    "type": "procedure_step",
                    "title": "Pre-Flight: Verify Access & Current State",
                    "content_type": "verification",
                    "estimated_minutes": 5,
                    "description": (
                        "Log into the SonicWall at **[VAR:firewall_ip]** for **[VAR:client_name]**.\n\n"
                        "**Verify:**\n"
                        "1. Navigate to **System > Status** — note current firmware version\n"
                        "2. Confirm the appliance model matches **[VAR:firewall_model]**\n"
                        "3. Check **System > Diagnostics > Tech Support Report** — note any existing issues\n"
                        "4. Verify HA status if applicable (both units should be in sync)\n"
                        "5. Check VPN tunnel status — note how many tunnels are active\n"
                        "6. Confirm you are within the maintenance window: **[VAR:maintenance_window]**"
                    ),
                    "verification": {
                        "type": "checkbox",
                        "prompt": "Logged in, current firmware noted, and within maintenance window?"
                    },
                },
                {
                    "id": "step_2",
                    "type": "procedure_step",
                    "title": "Export Configuration Backup",
                    "content_type": "action",
                    "estimated_minutes": 3,
                    "description": (
                        "**Create a full configuration backup before any changes.**\n\n"
                        "1. Navigate to **System > Settings > Export Settings**\n"
                        "2. Click **Export** to download the `.exp` configuration file\n"
                        "3. Save the file as: `[VAR:client_name]_SonicWall_[VAR:firewall_model]_pre-firmware_YYYY-MM-DD.exp`\n"
                        "4. Store the backup in the client's documentation folder and password vault\n\n"
                        "**Also export:**\n"
                        "- **System > Diagnostics > Tech Support Report** (for rollback reference)\n\n"
                        "**Critical:** Do NOT proceed without a verified backup file."
                    ),
                    "verification": {
                        "type": "checkbox",
                        "prompt": "Configuration backup exported and stored securely?"
                    },
                },
                {
                    "id": "step_3",
                    "type": "procedure_step",
                    "title": "Check for Available Firmware",
                    "content_type": "action",
                    "estimated_minutes": 5,
                    "description": (
                        "**Check MySonicWall for the latest firmware:**\n\n"
                        "1. Navigate to **System > Settings > Firmware & Backups**\n"
                        "2. If connected to MySonicWall, available firmware will show automatically\n"
                        "3. Alternatively, log into [mysonicwall.com](https://mysonicwall.com) → **Product Management** → select this appliance → **Firmware**\n\n"
                        "**Before downloading, check:**\n"
                        "- Read the **Release Notes** for the new firmware version\n"
                        "- Look for any known issues that affect **[VAR:firewall_model]**\n"
                        "- Check if the upgrade path requires intermediate firmware versions\n"
                        "- Verify the firmware is marked **General Release** (not Early Release unless approved)\n\n"
                        "**Note the target firmware version in your session notes.**"
                    ),
                    "notes_enabled": True,
                    "verification": {
                        "type": "checkbox",
                        "prompt": "Target firmware identified and release notes reviewed?"
                    },
                },
                {
                    "id": "step_4",
                    "type": "procedure_step",
                    "title": "Upload & Install Firmware",
                    "content_type": "action",
                    "estimated_minutes": 15,
                    "warning_text": "The firewall will reboot during this step. All active connections will drop temporarily.",
                    "description": (
                        "**Install the firmware:**\n\n"
                        "1. Navigate to **System > Settings > Firmware & Backups**\n"
                        "2. Upload the downloaded firmware file (or click **Download** if fetching from MySonicWall)\n"
                        "3. Select **Upload Firmware (with current settings)**\n"
                        "4. **Important:** Select **Create backup of current firmware** before proceeding\n"
                        "5. Click **Boot** to begin the upgrade\n\n"
                        "**The appliance will:**\n"
                        "- Save the current firmware to the backup partition\n"
                        "- Flash the new firmware\n"
                        "- Reboot (takes 3-8 minutes depending on model)\n\n"
                        "**For HA pairs:** Update the secondary unit first, verify, then failover and update the primary.\n\n"
                        "**Wait for the appliance to come back online.** Monitor the management IP with continuous ping."
                    ),
                    "commands": [
                        {"language": "bash", "code": "ping -t [VAR:firewall_ip]", "label": "Monitor reboot (Windows)"},
                        {"language": "bash", "code": "ping [VAR:firewall_ip]", "label": "Monitor reboot (Mac/Linux)"},
                    ],
                    "verification": {
                        "type": "checkbox",
                        "prompt": "Firmware installed and appliance is back online?"
                    },
                },
                {
                    "id": "step_5",
                    "type": "procedure_step",
                    "title": "Post-Update Verification",
                    "content_type": "verification",
                    "estimated_minutes": 10,
                    "description": (
                        "**Verify the firmware update was successful:**\n\n"
                        "1. Log into **[VAR:firewall_ip]** — confirm the login page loads\n"
                        "2. Navigate to **System > Status** — confirm new firmware version\n"
                        "3. Check **System > Diagnostics > Tech Support Report** for errors\n\n"
                        "**Verify critical services:**\n"
                        "- [ ] Internet connectivity passing through the firewall\n"
                        "- [ ] VPN tunnels re-established (compare count from pre-flight)\n"
                        "- [ ] NAT rules working (test external-facing services)\n"
                        "- [ ] Content filtering / security services active\n"
                        "- [ ] DHCP leases being issued (if SonicWall is DHCP server)\n"
                        "- [ ] SSL VPN / Global VPN Client connectivity\n"
                        "- [ ] HA sync status (if applicable)\n\n"
                        "**If anything is broken:** Reboot to the backup firmware partition via **System > Settings > Firmware & Backups** → Boot backup firmware."
                    ),
                    "verification": {
                        "type": "checkbox",
                        "prompt": "All services verified and operational on new firmware?"
                    },
                },
                {
                    "id": "step_6",
                    "type": "procedure_step",
                    "title": "Document & Close",
                    "content_type": "informational",
                    "estimated_minutes": 5,
                    "description": (
                        "**Update documentation:**\n\n"
                        "1. Update the client's asset record with the new firmware version\n"
                        "2. Note the upgrade date and any issues encountered\n"
                        "3. Export a fresh **post-update configuration backup**\n"
                        "4. Update the ticket **[VAR:ticket_number]** with results\n\n"
                        "**Summary for [VAR:client_name]:**\n"
                        "- Appliance: **[VAR:firewall_model]** at **[VAR:firewall_ip]**\n"
                        "- Previous firmware: **[VAR:current_firmware]**\n"
                        "- New firmware: *(note in session)*\n"
                        "- Status: Operational"
                    ),
                    "verification": {
                        "type": "checkbox",
                        "prompt": "Documentation updated and post-upgrade backup stored?"
                    },
                },
                {
                    "id": "step_end",
                    "type": "procedure_end",
                    "title": "Firmware Update Complete",
                    "description": (
                        "SonicWall firmware update complete for **[VAR:client_name]**.\n\n"
                        "- Appliance: **[VAR:firewall_model]** at **[VAR:firewall_ip]**\n"
                        "- All services verified operational\n"
                        "- Configuration backup stored\n\n"
                        "**Follow-up:** Monitor for 24-48 hours for any stability issues."
                    ),
                },
            ]
        },
    }


def get_windows_update_dc_flow() -> dict[str, Any]:
    """Windows Server 2022 Domain Controller — Windows Update maintenance."""
    return {
        "name": "Windows Updates — Domain Controller (Server 2022)",
        "description": "Check for and install Windows updates on a Windows Server 2022 domain controller. Includes AD health checks, DFSR/SYSVOL verification, proper reboot sequencing, and post-update replication validation. Designed for batch execution across multiple DCs.",
        "tree_type": "maintenance",
        "tags": ["windows-server", "domain-controller", "windows-update", "active-directory", "maintenance"],
        "intake_form": [
            {
                "variable_name": "server_name",
                "label": "Server Name",
                "field_type": "text",
                "required": True,
                "placeholder": "e.g. DC01",
                "help_text": "Hostname of the domain controller",
                "group_name": "Server Details",
                "display_order": 1,
            },
            {
                "variable_name": "server_ip",
                "label": "Server IP Address",
                "field_type": "ip_address",
                "required": True,
                "placeholder": "e.g. 10.0.1.10",
                "group_name": "Server Details",
                "display_order": 2,
            },
            {
                "variable_name": "domain_name",
                "label": "Domain Name",
                "field_type": "text",
                "required": True,
                "placeholder": "e.g. contoso.local",
                "group_name": "Server Details",
                "display_order": 3,
            },
            {
                "variable_name": "is_fsmo_holder",
                "label": "FSMO Role Holder?",
                "field_type": "select",
                "required": True,
                "options": ["No — standard DC", "Yes — holds one or more FSMO roles", "Unknown — will check"],
                "help_text": "FSMO holders need extra care during patching",
                "group_name": "Server Details",
                "display_order": 4,
            },
            {
                "variable_name": "maintenance_window",
                "label": "Maintenance Window",
                "field_type": "text",
                "required": True,
                "placeholder": "e.g. Sun 2am-6am EST",
                "group_name": "Scheduling",
                "display_order": 5,
            },
            {
                "variable_name": "client_name",
                "label": "Client Name",
                "field_type": "text",
                "required": True,
                "placeholder": "e.g. Contoso Ltd",
                "group_name": "Scheduling",
                "display_order": 6,
            },
            {
                "variable_name": "ticket_number",
                "label": "Ticket Number",
                "field_type": "text",
                "required": False,
                "placeholder": "e.g. TKT-2024-1234",
                "group_name": "Scheduling",
                "display_order": 7,
            },
        ],
        "tree_structure": {
            "steps": [
                {
                    "id": "step_1",
                    "type": "procedure_step",
                    "title": "Pre-Flight: AD Health Check",
                    "content_type": "verification",
                    "estimated_minutes": 10,
                    "description": (
                        "Connect to **[VAR:server_name]** (**[VAR:server_ip]**) for **[VAR:client_name]** via RDP or remote PowerShell.\n\n"
                        "**Run the following health checks before patching:**"
                    ),
                    "commands": [
                        {"language": "powershell", "code": "# Check AD replication status\nrepadmin /replsummary\n\n# Check for replication failures\nrepadmin /showrepl", "label": "AD Replication Status"},
                        {"language": "powershell", "code": "# Run DC diagnostics\ndcdiag /v | Select-String -Pattern 'passed|failed'", "label": "DC Diagnostics"},
                        {"language": "powershell", "code": "# Check SYSVOL/NETLOGON shares\nnet share | Select-String 'SYSVOL|NETLOGON'\n\n# Check DFSR health\nGet-WinEvent -LogName 'DFS Replication' -MaxEvents 10 | Format-Table TimeCreated, Message -Wrap", "label": "SYSVOL & DFSR Check"},
                        {"language": "powershell", "code": "# Check FSMO roles on this DC\nnetdom query fsmo", "label": "FSMO Role Check"},
                        {"language": "powershell", "code": "# Check disk space (need at least 10GB free on C:)\nGet-PSDrive C | Select-Object @{N='FreeGB';E={[math]::Round($_.Free/1GB,2)}}", "label": "Disk Space Check"},
                    ],
                    "verification": {
                        "type": "checkbox",
                        "prompt": "AD replication healthy, dcdiag passing, SYSVOL shared, sufficient disk space?"
                    },
                },
                {
                    "id": "step_2",
                    "type": "procedure_step",
                    "title": "Create System State Backup",
                    "content_type": "action",
                    "estimated_minutes": 15,
                    "description": (
                        "**Create a system state backup before patching.**\n\n"
                        "This captures Active Directory, SYSVOL, registry, and boot files — essential for DC recovery."
                    ),
                    "commands": [
                        {"language": "powershell", "code": "# Start system state backup (requires Windows Server Backup feature)\nwbadmin start systemstatebackup -backupTarget:C: -quiet", "label": "System State Backup"},
                        {"language": "powershell", "code": "# If Windows Server Backup not installed:\nInstall-WindowsFeature Windows-Server-Backup -IncludeManagementTools", "label": "Install Backup Feature (if needed)"},
                    ],
                    "verification": {
                        "type": "checkbox",
                        "prompt": "System state backup completed successfully?"
                    },
                },
                {
                    "id": "step_3",
                    "type": "procedure_step",
                    "title": "Check for & Review Available Updates",
                    "content_type": "action",
                    "estimated_minutes": 10,
                    "description": (
                        "**Scan for available updates and review before installing:**"
                    ),
                    "commands": [
                        {"language": "powershell", "code": "# Install PSWindowsUpdate module if not present\nif (-not (Get-Module -ListAvailable PSWindowsUpdate)) {\n    Install-Module PSWindowsUpdate -Force -Confirm:$false\n}\nImport-Module PSWindowsUpdate\n\n# Check for available updates\nGet-WindowsUpdate -MicrosoftUpdate | Format-Table -AutoSize KB, Size, Title", "label": "List Available Updates"},
                    ],
                    "notes_enabled": True,
                    "verification": {
                        "type": "checkbox",
                        "prompt": "Available updates reviewed — no known bad patches in the list?"
                    },
                },
                {
                    "id": "step_4",
                    "type": "procedure_step",
                    "title": "Install Updates & Reboot",
                    "content_type": "action",
                    "estimated_minutes": 30,
                    "warning_text": "The server will reboot. All users authenticating against this DC will failover to another DC. Ensure at least one other DC is available.",
                    "description": (
                        "**Install all approved updates:**\n\n"
                        "**Important for [VAR:domain_name]:**\n"
                        "- If this is the **only DC**, schedule downtime — users will lose authentication during reboot\n"
                        "- If FSMO holder: verify other DCs can service requests during reboot\n"
                        "- Reboot will take 5-20 minutes depending on update count"
                    ),
                    "commands": [
                        {"language": "powershell", "code": "# Install all updates and auto-reboot\nInstall-WindowsUpdate -MicrosoftUpdate -AcceptAll -AutoReboot", "label": "Install Updates (auto-reboot)"},
                        {"language": "powershell", "code": "# Or install without auto-reboot (manual control)\nInstall-WindowsUpdate -MicrosoftUpdate -AcceptAll -IgnoreReboot\n\n# Then reboot manually when ready\nRestart-Computer -Force", "label": "Install Updates (manual reboot)"},
                        {"language": "bash", "code": "ping -t [VAR:server_ip]", "label": "Monitor reboot (Windows)"},
                    ],
                    "verification": {
                        "type": "checkbox",
                        "prompt": "Updates installed and server is back online?"
                    },
                },
                {
                    "id": "step_5",
                    "type": "procedure_step",
                    "title": "Post-Update: Verify AD Health",
                    "content_type": "verification",
                    "estimated_minutes": 10,
                    "description": (
                        "**After the server comes back online, verify everything is healthy:**"
                    ),
                    "commands": [
                        {"language": "powershell", "code": "# Verify replication is working\nrepadmin /replsummary\nrepadmin /showrepl", "label": "AD Replication Check"},
                        {"language": "powershell", "code": "# Run DC diagnostics again\ndcdiag /v | Select-String -Pattern 'passed|failed'", "label": "DC Diagnostics"},
                        {"language": "powershell", "code": "# Verify SYSVOL/NETLOGON shares\nnet share | Select-String 'SYSVOL|NETLOGON'\n\n# Verify DNS is resolving\nnslookup [VAR:domain_name] [VAR:server_ip]", "label": "Shares & DNS Check"},
                        {"language": "powershell", "code": "# Check for pending reboots\nGet-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WindowsUpdate\\Auto Update\\RebootRequired' -ErrorAction SilentlyContinue\nGet-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Component Based Servicing\\RebootPending' -ErrorAction SilentlyContinue", "label": "Pending Reboot Check"},
                        {"language": "powershell", "code": "# Verify installed updates\nGet-HotFix | Sort-Object InstalledOn -Descending | Select-Object -First 10 | Format-Table HotFixID, InstalledOn, Description", "label": "Verify Installed Updates"},
                    ],
                    "verification": {
                        "type": "checkbox",
                        "prompt": "AD replication healthy, dcdiag passing, DNS resolving, shares accessible?"
                    },
                },
                {
                    "id": "step_6",
                    "type": "procedure_step",
                    "title": "Document & Close",
                    "content_type": "informational",
                    "estimated_minutes": 5,
                    "description": (
                        "**Update documentation:**\n\n"
                        "1. Record which KB updates were installed\n"
                        "2. Note the new OS build number: `winver` or `[System.Environment]::OSVersion`\n"
                        "3. Update the client's patching log\n"
                        "4. Update ticket **[VAR:ticket_number]**\n\n"
                        "**Summary for [VAR:client_name]:**\n"
                        "- Server: **[VAR:server_name]** (**[VAR:server_ip]**)\n"
                        "- Domain: **[VAR:domain_name]**\n"
                        "- FSMO: **[VAR:is_fsmo_holder]**\n"
                        "- Status: Patched and operational"
                    ),
                    "verification": {
                        "type": "checkbox",
                        "prompt": "Patching log updated and ticket documented?"
                    },
                },
                {
                    "id": "step_end",
                    "type": "procedure_end",
                    "title": "Windows Updates Complete",
                    "description": (
                        "Windows updates installed on **[VAR:server_name]** for **[VAR:client_name]**.\n\n"
                        "- Domain: **[VAR:domain_name]**\n"
                        "- AD replication: Healthy\n"
                        "- All services verified operational\n\n"
                        "**Follow-up:** Monitor event logs for 24 hours for any post-patch issues."
                    ),
                },
            ]
        },
    }


def get_ssl_cert_renewal_flow() -> dict[str, Any]:
    """SSL Certificate Renewal — renew and install SSL certs for client websites."""
    return {
        "name": "SSL Certificate Renewal",
        "description": "Renew and install SSL/TLS certificates for client websites and web applications. Covers CSR generation, certificate purchase/renewal, installation, and validation. Designed for batch execution across multiple client domains.",
        "tree_type": "maintenance",
        "tags": ["ssl", "certificate", "tls", "website", "maintenance", "security"],
        "intake_form": [
            {
                "variable_name": "domain_name",
                "label": "Domain Name",
                "field_type": "text",
                "required": True,
                "placeholder": "e.g. www.contoso.com",
                "help_text": "Primary domain the certificate covers",
                "group_name": "Certificate Details",
                "display_order": 1,
            },
            {
                "variable_name": "cert_type",
                "label": "Certificate Type",
                "field_type": "select",
                "required": True,
                "options": [
                    "Single Domain (DV)",
                    "Wildcard (*.domain.com)",
                    "Multi-Domain / SAN",
                    "Extended Validation (EV)",
                    "Let's Encrypt (Free/Auto)",
                ],
                "group_name": "Certificate Details",
                "display_order": 2,
            },
            {
                "variable_name": "hosting_type",
                "label": "Hosting / Server Type",
                "field_type": "select",
                "required": True,
                "options": [
                    "IIS (Windows Server)",
                    "Apache (Linux)",
                    "Nginx (Linux)",
                    "cPanel / Plesk",
                    "Azure App Service",
                    "AWS (ELB / CloudFront)",
                    "Cloudflare",
                    "Other",
                ],
                "group_name": "Server Details",
                "display_order": 3,
            },
            {
                "variable_name": "server_ip",
                "label": "Server IP / Hostname",
                "field_type": "text",
                "required": True,
                "placeholder": "e.g. 203.0.113.50 or web01.contoso.com",
                "help_text": "IP or hostname of the web server hosting this site",
                "group_name": "Server Details",
                "display_order": 4,
            },
            {
                "variable_name": "cert_provider",
                "label": "Certificate Provider",
                "field_type": "select",
                "required": True,
                "options": [
                    "Let's Encrypt (Certbot)",
                    "DigiCert",
                    "Sectigo / Comodo",
                    "GoDaddy",
                    "GlobalSign",
                    "Namecheap",
                    "Other",
                ],
                "group_name": "Certificate Details",
                "display_order": 5,
            },
            {
                "variable_name": "expiry_date",
                "label": "Current Cert Expiry Date",
                "field_type": "text",
                "required": False,
                "placeholder": "e.g. 2026-03-15",
                "help_text": "When the current certificate expires (YYYY-MM-DD)",
                "group_name": "Certificate Details",
                "display_order": 6,
            },
            {
                "variable_name": "client_name",
                "label": "Client Name",
                "field_type": "text",
                "required": True,
                "placeholder": "e.g. Contoso Ltd",
                "group_name": "Project Info",
                "display_order": 7,
            },
            {
                "variable_name": "ticket_number",
                "label": "Ticket Number",
                "field_type": "text",
                "required": False,
                "placeholder": "e.g. TKT-2024-1234",
                "group_name": "Project Info",
                "display_order": 8,
            },
        ],
        "tree_structure": {
            "steps": [
                {
                    "id": "step_1",
                    "type": "procedure_step",
                    "title": "Pre-Flight: Check Current Certificate",
                    "content_type": "verification",
                    "estimated_minutes": 5,
                    "description": (
                        "**Verify the current certificate status for [VAR:domain_name] ([VAR:client_name]):**\n\n"
                        "Check the current certificate from the command line or browser:"
                    ),
                    "commands": [
                        {"language": "bash", "code": "# Check current certificate details and expiry\nopenssl s_client -connect [VAR:domain_name]:443 -servername [VAR:domain_name] 2>/dev/null | openssl x509 -noout -dates -subject -issuer", "label": "Check Current Cert (Linux/Mac)"},
                        {"language": "powershell", "code": "# Check current certificate from Windows\n$uri = 'https://[VAR:domain_name]'\n$req = [Net.HttpWebRequest]::Create($uri)\n$req.AllowAutoRedirect = $false\ntry { $req.GetResponse() | Out-Null } catch {}\n$cert = $req.ServicePoint.Certificate\nWrite-Host \"Subject: $($cert.Subject)\"\nWrite-Host \"Issuer: $($cert.Issuer)\"\nWrite-Host \"Expires: $($cert.GetExpirationDateString())\"", "label": "Check Current Cert (Windows)"},
                        {"language": "bash", "code": "# Quick SSL test via curl\ncurl -vI https://[VAR:domain_name] 2>&1 | grep -E 'expire|subject|issuer|SSL'", "label": "Quick SSL Check"},
                    ],
                    "verification": {
                        "type": "checkbox",
                        "prompt": "Current certificate status verified — expiry date confirmed?"
                    },
                },
                {
                    "id": "step_2",
                    "type": "procedure_step",
                    "title": "Generate CSR (if required)",
                    "content_type": "action",
                    "estimated_minutes": 10,
                    "description": (
                        "**Generate a Certificate Signing Request (CSR) if needed.**\n\n"
                        "Skip this step if using **Let's Encrypt** (certbot handles CSR automatically) or if the provider generates it for you.\n\n"
                        "Generate the CSR on the target server (**[VAR:server_ip]**):"
                    ),
                    "commands": [
                        {"language": "bash", "code": "# Generate private key and CSR (Linux/Apache/Nginx)\nopenssl req -new -newkey rsa:2048 -nodes \\\n  -keyout [VAR:domain_name].key \\\n  -out [VAR:domain_name].csr \\\n  -subj \"/C=US/ST=State/L=City/O=[VAR:client_name]/CN=[VAR:domain_name]\"", "label": "Generate CSR (OpenSSL)"},
                        {"language": "powershell", "code": "# Generate CSR on IIS (Windows)\n# Open IIS Manager > Server Certificates > Create Certificate Request\n# Or via PowerShell:\n$params = @{\n    Subject = 'CN=[VAR:domain_name],O=[VAR:client_name]'\n    KeyLength = 2048\n    HashAlgorithm = 'SHA256'\n    CertStoreLocation = 'Cert:\\LocalMachine\\My'\n}\n$cert = New-SelfSignedCertificate @params\n# Then export CSR via certreq or IIS Manager", "label": "Generate CSR (IIS/Windows)"},
                    ],
                    "verification": {
                        "type": "checkbox",
                        "prompt": "CSR generated (or skipped if using auto-renewal)?"
                    },
                },
                {
                    "id": "step_3",
                    "type": "procedure_step",
                    "title": "Purchase / Renew Certificate",
                    "content_type": "action",
                    "estimated_minutes": 15,
                    "description": (
                        "**Renew or purchase the certificate from [VAR:cert_provider]:**\n\n"
                        "**For Let's Encrypt:**"
                    ),
                    "commands": [
                        {"language": "bash", "code": "# Let's Encrypt renewal via Certbot\nsudo certbot renew --cert-name [VAR:domain_name]\n\n# Or for a new cert:\nsudo certbot certonly --webroot -w /var/www/html -d [VAR:domain_name]", "label": "Certbot Renewal"},
                    ],
                    "notes_enabled": True,
                    "verification": {
                        "type": "checkbox",
                        "prompt": "New certificate obtained — cert files downloaded/generated?"
                    },
                },
                {
                    "id": "step_4",
                    "type": "procedure_step",
                    "title": "Install Certificate on Server",
                    "content_type": "action",
                    "estimated_minutes": 10,
                    "description": (
                        "**Install the new certificate on [VAR:hosting_type] at [VAR:server_ip]:**\n\n"
                        "Follow the appropriate process for your hosting type. After installation, restart the web service to load the new certificate."
                    ),
                    "commands": [
                        {"language": "bash", "code": "# Apache — update ssl.conf and restart\nsudo cp [VAR:domain_name].crt /etc/ssl/certs/\nsudo cp [VAR:domain_name].key /etc/ssl/private/\nsudo systemctl restart apache2", "label": "Install on Apache"},
                        {"language": "bash", "code": "# Nginx — update server block and restart\nsudo cp [VAR:domain_name].crt /etc/nginx/ssl/\nsudo cp [VAR:domain_name].key /etc/nginx/ssl/\nsudo nginx -t && sudo systemctl restart nginx", "label": "Install on Nginx"},
                        {"language": "powershell", "code": "# IIS — Import certificate via PowerShell\n$cert = Import-PfxCertificate -FilePath 'C:\\certs\\[VAR:domain_name].pfx' -CertStoreLocation 'Cert:\\LocalMachine\\My' -Password (ConvertTo-SecureString -String 'YourPfxPassword' -AsPlainText -Force)\n\n# Then bind in IIS Manager:\n# Sites > [site] > Bindings > Edit HTTPS > Select new certificate", "label": "Install on IIS"},
                    ],
                    "verification": {
                        "type": "checkbox",
                        "prompt": "Certificate installed and web service restarted?"
                    },
                },
                {
                    "id": "step_5",
                    "type": "procedure_step",
                    "title": "Validate New Certificate",
                    "content_type": "verification",
                    "estimated_minutes": 5,
                    "description": (
                        "**Verify the new certificate is active and valid:**"
                    ),
                    "commands": [
                        {"language": "bash", "code": "# Verify the new cert is serving\nopenssl s_client -connect [VAR:domain_name]:443 -servername [VAR:domain_name] 2>/dev/null | openssl x509 -noout -dates -subject\n\n# Verify certificate chain is complete\nopenssl s_client -connect [VAR:domain_name]:443 -servername [VAR:domain_name] 2>/dev/null | grep -E 'Verify return|depth'", "label": "Verify New Cert"},
                        {"language": "bash", "code": "# Test HTTPS response\ncurl -I https://[VAR:domain_name]", "label": "Test HTTPS"},
                    ],
                    "reference_url": "https://www.ssllabs.com/ssltest/",
                    "verification": {
                        "type": "checkbox",
                        "prompt": "New certificate verified — correct domain, valid dates, complete chain?"
                    },
                },
                {
                    "id": "step_6",
                    "type": "procedure_step",
                    "title": "Document & Close",
                    "content_type": "informational",
                    "estimated_minutes": 3,
                    "description": (
                        "**Update documentation:**\n\n"
                        "1. Record the new certificate expiry date\n"
                        "2. Update the client's certificate inventory\n"
                        "3. Set a calendar reminder for 30 days before the new expiry\n"
                        "4. Store any private keys securely in the password vault\n"
                        "5. Update ticket **[VAR:ticket_number]**\n\n"
                        "**Summary for [VAR:client_name]:**\n"
                        "- Domain: **[VAR:domain_name]**\n"
                        "- Type: **[VAR:cert_type]**\n"
                        "- Provider: **[VAR:cert_provider]**\n"
                        "- Server: **[VAR:hosting_type]** at **[VAR:server_ip]**\n"
                        "- Previous expiry: **[VAR:expiry_date]**\n"
                        "- New expiry: *(note in session)*\n"
                        "- Status: Renewed and operational"
                    ),
                    "verification": {
                        "type": "checkbox",
                        "prompt": "Certificate inventory updated and renewal reminder set?"
                    },
                },
                {
                    "id": "step_end",
                    "type": "procedure_end",
                    "title": "SSL Certificate Renewed",
                    "description": (
                        "SSL certificate renewed for **[VAR:domain_name]** (**[VAR:client_name]**).\n\n"
                        "- Certificate type: **[VAR:cert_type]**\n"
                        "- Provider: **[VAR:cert_provider]**\n"
                        "- Hosting: **[VAR:hosting_type]**\n"
                        "- All validations passed\n\n"
                        "**Follow-up:** Verify no mixed-content warnings and test from multiple browsers."
                    ),
                },
            ]
        },
    }


# =============================================================================
# SEEDING FUNCTIONS
# =============================================================================

async def get_admin_token(client: httpx.AsyncClient) -> str:
    """Authenticate and get admin token."""
    response = await client.post(
        f"{API_BASE_URL}/auth/login",
        data={"username": ADMIN_EMAIL, "password": ADMIN_PASSWORD},
    )
    if response.status_code != 200:
        raise Exception(f"Login failed ({response.status_code}): {response.text}")
    return response.json()["access_token"]


async def create_maintenance_flow(client: httpx.AsyncClient, token: str, flow_data: dict) -> dict | None:
    """Create a maintenance flow via the API. Returns None if it already exists."""
    headers = {"Authorization": f"Bearer {token}"}

    flow_data["is_default"] = True
    flow_data["is_public"] = True
    flow_data["status"] = "published"

    # Check if flow with same name exists
    list_response = await client.get(f"{API_BASE_URL}/trees", headers=headers, params={"tree_type": "maintenance"})
    if list_response.status_code == 200:
        existing = list_response.json()
        for tree in existing:
            if tree["name"] == flow_data["name"]:
                print(f"  [SKIP] Flow '{flow_data['name']}' already exists (ID: {tree['id']})")
                return None

    response = await client.post(
        f"{API_BASE_URL}/trees",
        json=flow_data,
        headers=headers,
    )

    if response.status_code not in (200, 201):
        raise Exception(f"Failed to create flow '{flow_data['name']}': {response.text}")

    tree = response.json()
    print(f"  [OK] Created flow '{flow_data['name']}' (ID: {tree['id']})")
    return tree


async def seed_maintenance_flows():
    """Main seeding function."""
    print("\n" + "=" * 60)
    print("  RESOLUTIONFLOW - Maintenance Flow Templates Seeder")
    print("=" * 60)

    async with httpx.AsyncClient(timeout=60.0) as client:
        try:
            health_check = await client.get(f"{API_BASE_URL.replace('/api/v1', '')}/health")
            if health_check.status_code != 200:
                print(f"\n[ERROR] API health check failed: {health_check.status_code}")
                return False
        except httpx.ConnectError:
            print("\n[ERROR] Cannot connect to API server")
            print(f"        Make sure the server is running at {API_BASE_URL}")
            return False

        print("\n[1/3] Authenticating...")
        try:
            token = await get_admin_token(client)
            print(f"       Logged in as {ADMIN_EMAIL}")
        except Exception as e:
            print(f"       [ERROR] Failed to authenticate: {e}")
            return False

        print("\n[2/3] Preparing maintenance flows...")
        flows_to_create = [
            get_sonicwall_firmware_flow(),
            get_windows_update_dc_flow(),
            get_ssl_cert_renewal_flow(),
        ]
        print(f"       Found {len(flows_to_create)} flows to seed\n")

        print("[3/3] Creating maintenance flows...")
        created_count = 0
        skipped_count = 0

        for flow_data in flows_to_create:
            try:
                result = await create_maintenance_flow(client, token, flow_data)
                if result:
                    created_count += 1
                else:
                    skipped_count += 1
            except Exception as e:
                print(f"  [FAIL] Failed to create '{flow_data['name']}': {e}")

        print("\n" + "=" * 60)
        print("  SEEDING COMPLETE")
        print("=" * 60)
        print(f"  Flows created: {created_count}")
        print(f"  Flows skipped (already exist): {skipped_count}")
        print()

        return True


def main():
    global ADMIN_EMAIL, ADMIN_PASSWORD, API_BASE_URL

    parser = argparse.ArgumentParser(description="Seed maintenance flow templates")
    parser.add_argument("--email", required=True, help="Admin email for authentication")
    parser.add_argument("--password", required=True, help="Admin password")
    parser.add_argument("--api-url", default=API_BASE_URL, help="API base URL")
    args = parser.parse_args()

    ADMIN_EMAIL = args.email
    ADMIN_PASSWORD = args.password
    API_BASE_URL = args.api_url

    asyncio.run(seed_maintenance_flows())


if __name__ == "__main__":
    main()
