#!/bin/bash
# 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.
# Complete Windows installer build: PyInstaller + NSIS
# Works on Linux using Wine Windows Python environment
#
# Prerequisites:
#   - wine (already installed)
#   - makensis (NSIS compiler)
#   - nssm.exe in windows/ directory (download from nssm.cc)
#
# This script:
#   1. Builds Windows .exe binaries with PyInstaller (via Wine)
#   2. Packages them with NSIS installer with interactive config page

set -e
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
cd "$SCRIPT_DIR"

WINEPYTHON="./python-win/python.exe"
DIST_DIR="./dist"
BUILD_DIR="./build"

echo "=== Hermes Node Agent: Windows Installer Build ==="
echo ""

# ── Validation ────────────────────────────────────────────────────────────
if ! command -v makensis &>/dev/null; then
    echo "❌ NSIS (makensis) not installed"
    exit 1
fi

if [ ! -f "$WINEPYTHON" ]; then
    echo "❌ Wine Python not found: $WINEPYTHON"
    echo "   Run: wget https://www.python.org/ftp/python/3.13.1/python-3.13.1-embed-amd64.zip"
    echo "        unzip it to windows/python-win/"
    exit 1
fi

if [ ! -f "nssm.exe" ]; then
    echo "⚠️  NSSM not found in windows/"
    echo "   Download from https://nssm.cc/download (win64 version)"
    echo "   and place it at windows/nssm.exe"
    exit 1
fi

# ── Step 1: PyInstaller Build ─────────────────────────────────────────────
echo "Building Windows executables with PyInstaller..."

# Clean previous build
rm -rf "$DIST_DIR" "$BUILD_DIR"
mkdir -p "$DIST_DIR" "$BUILD_DIR"

# Build agent (console)
echo "  → hermes-node-agent.exe"
wine "$WINEPYTHON" -m PyInstaller ^
  --onefile ^
  --name hermes-node-agent ^
  --distpath "$DIST_DIR" ^
  --workpath "$BUILD_DIR/agent" ^
  --specpath windows ^
  --console ^
  --noconfirm ^
  hermes_node_agent.py 2>&1 | tail -3

# Build manager (GUI)
echo "  → hermes-node-manager.exe"
wine "$WINEPYTHON" -m PyInstaller ^
  --onefile ^
  --windowed ^
  --name hermes-node-manager ^
  --distpath "$DIST_DIR" ^
  --workpath "$BUILD_DIR/manager" ^
  --specpath windows ^
  --noconfirm ^
  agent-manager.py 2>&1 | tail -3

# Verify both exist
if [ ! -f "$DIST_DIR/hermes-node-agent.exe" ] || [ ! -f "$DIST_DIR/hermes-node-manager.exe" ]; then
    echo "❌ PyInstaller build failed"
    exit 1
fi

echo "✅ PyInstaller build complete:"
ls -lh "$DIST_DIR/"*.exe

# ── Step 2: Prepare NSIS installer files ──────────────────────────────────
echo ""
echo "Preparing NSIS installer..."

# Copy nssm and config template to dist
cp nssm.exe "$DIST_DIR/"
cp config-template.json "$DIST_DIR/config.json"

# ── Step 3: Write NSIS installer script ───────────────────────────────────
cat > "$DIST_DIR/installer.nsi" <<'NSIS'
!include "MUI2.nsh"
!include "LogicLib.nsh"

Name "Hermes Node Agent v2.0"
OutFile "hermes-node-agent-installer.exe"
InstallDir "$PROGRAMFILES64\HermesNode"
RequestExecutionLevel admin

!insertmacro MUI_PAGE_WELCOME
!insertmacro MUI_PAGE_DIRECTORY

; Custom configuration page (same prompts as Linux installer)
Page custom ConfigPageCreate ConfigPageLeave

!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_PAGE_FINISH
!insertmacro MUI_LANGUAGE "English"

; ── Variables ─────────────────────────────────────────────────────────────
Var GW_HOST
Var NODE_NAME
Var GW_TOKEN
Var NODE_NAME_DEFAULT

; Get computer name as default
Function .onInit
  System::Call "kernel32::GetComputerName(t .r0, *i ${NSIS_MAX_STRLEN}) i.r1"
  StrCpy $NODE_NAME_DEFAULT $0
FunctionEnd

; ── Configuration page UI ─────────────────────────────────────────────────
Function ConfigPageCreate
  nsDialogs::Create 1018
  Pop $0
  ${If} $0 == error
    Abort
  ${EndIf}
  
  ${NSD_CreateLabel} 0 0 100% 140u "Enter your Hermes Node Agent configuration:"
  Pop $0
  
  ${NSD_CreateLabel} 0 50u 100% 10u "Gateway URL (e.g., ws://gateway.example.com:8765):"
  Pop $0
  ${NSD_CreateText} 0 62u 100% 12u "ws://localhost:8765"
  Pop $GW_HOST
  
  ${NSD_CreateLabel} 0 82u 100% 10u "Node name (will appear in gateway):"
  Pop $0
  ${NSD_CreateText} 0 94u 100% 12u $NODE_NAME_DEFAULT
  Pop $NODE_NAME
  
  ${NSD_CreateLabel} 0 114u 100% 10u "Gateway token (from your gateway admin):"
  Pop $0
  ${NSD_CreatePassword} 0 126u 100% 12u ""
  Pop $GW_TOKEN
  
  nsDialogs::Show
FunctionEnd

Function ConfigPageLeave
  ${NSD_GetText} $GW_HOST $0
  ${NSD_GetText} $NODE_NAME $1
  ${NSD_GetText} $GW_TOKEN $2
  
  StrLen $3 $0
  ${If} $3 < 5
    MessageBox MB_ICONSTOP "Gateway URL is required and must be at least 5 characters."
    Abort
  ${EndIf}
FunctionEnd

; ── Install section ────────────────────────────────────────────────────────
Section "Install"
  SetOutPath "$INSTDIR"
  
  ; Copy PyInstaller-built executables
  File "hermes-node-agent.exe"
  File "hermes-node-manager.exe"
  
  ; Service wrapper (if present)
  IfFileExists "nssm.exe" 0 skip_nssm
    File "nssm.exe"
  skip_nssm:
  
  ; Get user-provided config
  ${NSD_GetText} $GW_HOST $0
  ${NSD_GetText} $NODE_NAME $1
  ${NSD_GetText} $GW_TOKEN $2
  
  ; Create config.json in Common AppData (C:\ProgramData\HermesNode)
  CreateDirectory "C:\ProgramData\HermesNode"
  
  ; Write config using PowerShell (simpler than NSIS string magic)
  nsExec::ExecToLog 'powershell -Command "[IO.File]::WriteAllText(''C:\ProgramData\HermesNode\config.json'', @"{{
    ''gateway_url'': ''$0'',
    ''node_name'': ''$1'',
    ''token'': ''$2'',
    ''reconnect_interval'': 5,
    ''heartbeat_interval'': 30,
    ''capabilities'': [''exec''],
    ''enable_browser'': $false,
    ''enable_computer_control'': $false,
    ''enable_desktop_observe'': $false,
    ''enable_audio_control'': $false,
    ''enable_camera_control'': $false,
    ''permissions'': @{
      ''deny'': @(''rm -rf /'', ''mkfs'', ''dd if=''),
      ''ask'': @(''sudo'', ''su'', ''passwd'', ''mount'', ''umount'', ''fdisk'', ''parted''),
      ''allow'': @(''ls'', ''pwd'', ''whoami'', ''hostname'', ''uname'', ''date'', ''uptime'', ''df'', ''free'', ''ps'', ''cat'', ''head'', ''tail'', ''grep'', ''find'', ''du'', ''ip'', ''ifconfig'', ''ping'', ''curl'', ''wget'', ''git'', ''python'', ''python3'', ''node'', ''npm'', ''systemctl'', ''journalctl'', ''dmesg'', ''docker'', ''kubectl'')
    }
  }}")"'
  
  ; Write uninstaller
  WriteUninstaller "$INSTDIR\uninstall.exe"
  
  ; Create start menu shortcuts
  CreateDirectory "$SMPROGRAMS\Hermes Node"
  CreateShortCut "$SMPROGRAMS\Hermes Node\Agent (Console).lnk" "$INSTDIR\hermes-node-agent.exe"
  CreateShortCut "$SMPROGRAMS\Hermes Node\Manager.lnk" "$INSTDIR\hermes-node-manager.exe"
  CreateShortCut "$SMPROGRAMS\Hermes Node\Uninstall.lnk" "$INSTDIR\uninstall.exe"
  
  ; Desktop shortcut
  CreateShortCut "$DESKTOP\Hermes Node Agent.lnk" "$INSTDIR\hermes-node-manager.exe"
  
  ; Install service — silently
  IfFileExists "$INSTDIR\nssm.exe" 0 no_nssm
    nsExec::ExecToLog '"$INSTDIR\nssm.exe" install HermesNodeAgent "$INSTDIR\hermes-node-agent.exe" --config "C:\ProgramData\HermesNode\config.json"'
    nsExec::ExecToLog '"$INSTDIR\nssm.exe" set HermesNodeAgent AppDirectory "$INSTDIR"'
    nsExec::ExecToLog '"$INSTDIR\nssm.exe" set HermesNodeAgent Start SERVICE_AUTO_START'
    nsExec::ExecToLog '"$INSTDIR\nssm.exe" set HermesNodeAgent AppRestartDelay 5000'
  no_nssm:
SectionEnd

; ── Uninstall section ─────────────────────────────────────────────────────
Section "Uninstall"
  IfFileExists "$INSTDIR\nssm.exe" 0 no_stop
    nsExec::ExecToLog '"$INSTDIR\nssm.exe" stop HermesNodeAgent'
    nsExec::ExecToLog '"$INSTDIR\nssm.exe" remove HermesNodeAgent confirm'
  no_stop:
  
  RMDir /r "$INSTDIR"
  RMDir /r "$SMPROGRAMS\Hermes Node"
  Delete "$DESKTOP\Hermes Node Agent.lnk"
  
  ; Optionally keep config (or remove? Up to you)
  ; RMDir /r "C:\ProgramData\HermesNode"
SectionEnd
NSIS

echo ""
echo "Compiling NSIS installer..."
makensis "$DIST_DIR/installer.nsi" 2>&1 | tail -5

if [ -f "$DIST_DIR/hermes-node-agent-installer.exe" ]; then
    echo ""
# ── Step 4: Build distribution bundle ────────────────────────────────────────
echo ""
echo "Building distribution bundle..."

# Components
cd "$SCRIPT_DIR"

BUNDLE_DIR="$DIST_DIR/bundle"
rm -rf "$BUNDLE_DIR"
mkdir -p "$BUNDLE_DIR"

# Linux installer
cp ../install.sh "$BUNDLE_DIR/hermes-node-agent-linux-installer.sh"

# Windows installer
cp "$DIST_DIR/hermes-node-agent-installer.exe" "$BUNDLE_DIR/hermes-node-agent-windows-installer.exe"

# Chrome extension zip (from hermes-node-chrome repo)
EXT_ZIP="/home/lisa/hermes-node-chrome/dist/hermes-node-chrome.zip"
if [ -f "$EXT_ZIP" ]; then
    cp "$EXT_ZIP" "$BUNDLE_DIR/hermes-browser-agent-chrome-extension.zip"
    echo "  ✓ Chrome extension zip included"
else
    echo "  ⚠️  Chrome extension zip not found at $EXT_ZIP"
fi

# README
if [ -f "../windows/README_BUILD.md" ]; then
    cp ../windows/README_BUILD.md "$BUNDLE_DIR/README.md"
fi

# Create bundle zip
rm -f "$DIST_DIR/hermes-node-agent-bundle.zip"
(cd "$BUNDLE_DIR" && zip -r "$DIST_DIR/hermes-node-agent-bundle.zip" . > /dev/null 2>&1)

if [ -f "$DIST_DIR/hermes-node-agent-bundle.zip" ]; then
    echo "✅ Distribution bundle created: $DIST_DIR/hermes-node-agent-bundle.zip"
    ls -lh "$DIST_DIR/hermes-node-agent-bundle.zip"
else
    echo "❌ Bundle creation failed"
    exit 1
fi

# Publish locally for testing
WEB_DIR="/home/web/lisa.nexlab.net/files"
mkdir -p "$WEB_DIR"
cp "$DIST_DIR/hermes-node-agent-installer.exe" "$WEB_DIR/hermes-node-agent-installer.exe"
cp "$DIST_DIR/hermes-node-agent-bundle.zip" "$WEB_DIR/hermes-node-agent-bundle.zip"
chmod 644 "$WEB_DIR/hermes-node-agent-installer.exe" "$WEB_DIR/hermes-node-agent-bundle.zip"
echo "✅ Published installer and bundle to web directory"

    echo "========== BUILD COMPLETE =========="
    echo "Installer created: $DIST_DIR/hermes-node-agent-installer.exe"
    echo "Size: $(du -h "$DIST_DIR/hermes-node-agent-installer.exe" | cut -f1)"
    echo ""
    echo "Next: copy to Windows for testing / distribution"
else
    echo "❌ Build failed"
    exit 1
fi
