# Copyright (C) 2026 Stefy Lanza <stefy@nexlab.net>
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyleft: this program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# Hermes Node Protocol
# Copyright (c) 2026 Stefy (nextime) Lanza <stefy@nexlab.net>
# All rights reserved.
# 
# This software is released under the MIT License with a copyleft clause.
# See the LICENSE file for full terms.
# Hermes Node Agent — Windows Installer (PowerShell)
# Installs the Hermes Node Agent as a Windows service using NSSM
# Requires: PowerShell 5+, Python 3.7+, Administrator rights

$ErrorActionPreference = "Stop"

Write-Host "=== Hermes Node Agent Windows Installer ===" -ForegroundColor Cyan
Write-Host ""

# ── 1. Verify running as Administrator ───────────────────────────────────────
if (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Host "ERROR: This installer must be run as Administrator." -ForegroundColor Red
    Write-Host "Right-click PowerShell → 'Run as Administrator'" -ForegroundColor Yellow
    exit 1
}

# ── 2. Locate or install Python ───────────────────────────────────────────────
Write-Host "[1/7] Checking Python installation..." -ForegroundColor Green

$pythonCmd = Get-Command python -ErrorAction SilentlyContinue
if (-not $pythonCmd) {
    Write-Host "Python not found in PATH. Attempting to locate..." -ForegroundColor Yellow
    $possiblePaths = @(
        "$env:ProgramFiles\Python39\python.exe",
        "$env:ProgramFiles\Python310\python.exe",
        "$env:ProgramFiles\Python311\python.exe",
        "$env:ProgramFiles(x86)\Python39\python.exe",
        "$env:USERPROFILE\AppData\Local\Programs\Python\Python39\python.exe"
    )
    $found = $false
    foreach ($p in $possiblePaths) {
        if (Test-Path $p) {
            $pythonCmd = $p
            $found = $true
            break
        }
    }
    if (-not $found) {
        Write-Host "ERROR: Python not found. Install from https://www.python.org/downloads/" -ForegroundColor Red
        exit 1
    }
}
Write-Host "  Found Python at: $($pythonCmd.Source ?? $pythonCmd)" -ForegroundColor Gray

# ── 3. Install websockets library ─────────────────────────────────────────────
Write-Host "[2/7] Installing Python dependencies..." -ForegroundColor Green
& $pythonCmd -m pip install --upgrade pip | Out-Null
& $pythonCmd -m pip install websockets | Out-Null
if ($LASTEXITCODE -ne 0) {
    Write-Host "ERROR: Failed to install websockets. Check pip output above." -ForegroundColor Red
    exit 1
}
Write-Host "  websockets installed" -ForegroundColor Gray

# ── 4. Create config directory ───────────────────────────────────────────────
Write-Host "[3/7] Creating configuration directories..." -ForegroundColor Green
$configDir = "$env:ProgramData\hermes-node"
$agentDir  = "C:\Program Files\Hermes Node"
New-Item -ItemType Directory -Force -Path $configDir | Out-Null
New-Item -ItemType Directory -Force -Path $agentDir  | Out-Null
Write-Host "  Config: $configDir" -ForegroundColor Gray
Write-Host "  Agent:  $agentDir" -ForegroundColor Gray

# ── 5. Deploy agent script ────────────────────────────────────────────────────
Write-Host "[4/7] Copying agent script..." -ForegroundColor Green
$sourceScript = "$PSScriptRoot\..\node-agent\hermes_node_agent.py"
if (-not (Test-Path $sourceScript)) {
    Write-Host "ERROR: Agent script not found at $sourceScript" -ForegroundColor Red
    Write-Host "Make sure you run this installer from the project root or adjust paths." -ForegroundColor Yellow
    exit 1
}
Copy-Item $sourceScript "$agentDir\hermes-node-agent.py" -Force
Write-Host "  Installed to: $agentDir\hermes-node-agent.py" -ForegroundColor Gray

# ── 6. Create config.json if missing ─────────────────────────────────────────
Write-Host "[5/7] Checking configuration..." -ForegroundColor Green
$configPath = "$configDir\config.json"
if (-not (Test-Path $configPath)) {
    Write-Host "  Creating example config (YOU MUST EDIT THIS!)" -ForegroundColor Yellow

    # Generate a random token
    $tokenBytes = New-Object byte[] 16
    (New-Object System.Security.Cryptography.RNGCryptoServiceProvider).GetBytes($tokenBytes)
    $token = ($tokenBytes | ForEach-Object { $_.ToString("x2") }) -join ''

    $config = @{
        gateway_url       = "wss://YOUR-GATEWAY-HOST:8765"
        node_name         = $env:COMPUTERNAME
        token             = $token
        sexec_path        = "$env:USERPROFILE\.openclaw\skills\sexec\sexec.ps1"
        reconnect_interval = 5
        heartbeat_interval = 30
    } | ConvertTo-Json -Depth 3

    $config | Out-File -FilePath $configPath -Encoding UTF8
    Write-Host "  Config written to: $configPath" -ForegroundColor Yellow
    Write-Host "  ⚠️  EDIT THIS FILE: Set gateway_url and verify node_name/token" -ForegroundColor Yellow
} else {
    Write-Host "  Config already exists, skipping." -ForegroundColor Gray
}

# ── 7. Check for NSSM and offer service registration ──────────────────────────
Write-Host "[6/7] Service registration..." -ForegroundColor Green

$nssmPath = Get-Command nssm -ErrorAction SilentlyContinue
if ($nssmPath) {
    Write-Host "  NSSM found — installing as Windows service..." -ForegroundColor Green
    & nssm install HermesNodeAgent "`"$pythonCmd`"" "`"$agentDir\hermes-node-agent.py`" --config `"$configPath`""
    if ($LASTEXITCODE -ne 0) {
        Write-Host "  NSSM install failed, will use Task Scheduler instead" -ForegroundColor Yellow
        $nssmPath = $null
    } else {
        nssm set HermesNodeAgent AppDirectory "`"$agentDir`""
        nssm set HermesNodeAgent Start SERVICE_AUTO_START
        nssm set HermesNodeAgent AppRestartDelay 5000
        Write-Host "  Service 'HermesNodeAgent' registered with NSSM" -ForegroundColor Green
    }
}

if (-not $nssmPath) {
    Write-Host "  NSSM not found — registering via Task Scheduler..." -ForegroundColor Yellow
    Write-Host "  (Download NSSM from https://nssm.cc/ for better service management)" -ForegroundColor Gray

    $action    = New-ScheduledTaskAction -Execute "`"$pythonCmd`"" -Argument "`"$agentDir\hermes-node-agent.py`" --config `"$configPath`""
    $trigger   = New-ScheduledTaskTrigger -AtStartup
    $settings  = New-ScheduledTaskSettingsSet -AllowStartIfOnBatteries -DontStopIfGoingOnBatteries -StartWhenAvailable -ExecutionTimeLimit 0
    $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest

    Register-ScheduledTask -TaskName "HermesNodeAgent" -Action $action -Trigger $trigger -Settings $settings -Principal $principal -Force | Out-Null
    Write-Host "  Scheduled task 'HermesNodeAgent' created" -ForegroundColor Green
}

# ── 8. Summary ────────────────────────────────────────────────────────────────
Write-Host ""
Write-Host "✅ Installation complete!" -ForegroundColor Green
Write-Host ""
Write-Host "=== Next Steps ===" -ForegroundColor Cyan
Write-Host "1. Edit config:  notepad $configPath" -ForegroundColor White
Write-Host "   → Set gateway_url to your gateway's address (wss://host:8765)" -ForegroundColor Gray
Write-Host "   → Verify token matches the entry in gateway's config.json" -ForegroundColor Gray
Write-Host ""
Write-Host "2. Verify service:" -ForegroundColor White
if ($nssmPath) {
    Write-Host "   nssm status HermesNodeAgent" -ForegroundColor Gray
    Write-Host "   nssm start HermesNodeAgent" -ForegroundColor Gray
} else {
    Write-Host "   Get-ScheduledTask HermesNodeAgent" -ForegroundColor Gray
    Write-Host "   Start-ScheduledTask HermesNodeAgent" -ForegroundColor Gray
}
Write-Host ""
Write-Host "3. Check logs:" -ForegroundColor White
Write-Host "   Get-Content $configDir\hermes-node-agent.log -Wait -Tail 50" -ForegroundColor Gray
Write-Host ""
Write-Host "=== Important ===" -ForegroundColor Yellow
Write-Host "The agent runs as SYSTEM if using Task Scheduler, or as LocalSystem if using NSSM." -ForegroundColor Gray
Write-Host "Ensure the sexec.ps1 script exists at the configured path if using permissions." -ForegroundColor Gray
Write-Host ""
