functions/Install-SiteForgeProject.ps1

function Install-SiteForgeProject {
    <#
    .SYNOPSIS
        Fully automates deployment of a new website on Ubuntu using PowerShell + NGINX.
        Handles installs, SSL, firewall, Fail2Ban, and SSH (if needed).
    #>


    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $false)] [string]$Domain,
        [Parameter(Mandatory = $false)] [string]$Repo,
        [Parameter(Mandatory = $false)] [string]$Email,
        [switch]$ForceReinstall,
        [switch]$UseSSH,
        [switch]$EnableFirewall,
        [switch]$EnableFail2Ban,
        [switch]$AutoDNSCheck
    )

    Write-Host "`n🚀 Launching SiteForge Project Installer..." -ForegroundColor Cyan

    # --- Step 0: Collect inputs ---
    if (-not $Domain) { $Domain = Read-Host "Enter your primary domain (e.g. example.com)" }
    if (-not $Repo)   { $Repo   = Read-Host "Enter your Git repository URL (HTTPS or SSH)" }
    if (-not $Email)  { $Email  = Read-Host "Enter your contact email for SSL + SSH key" }

    if (-not $Domain -or -not $Repo -or -not $Email) {
        Write-Host "❌ Missing required parameters. Exiting." -ForegroundColor Red
        return
    }

    # --- Step 0.5: DNS validation ---
    if ($AutoDNSCheck) {
        Write-Host "`n🌍 Auto DNS check enabled — verifying $Domain..." -ForegroundColor Cyan
        for ($i = 1; $i -le 10; $i++) {
            Write-Host "🔎 Attempt $i/10..." -ForegroundColor Gray
            if (Test-SiteForgeDNS -Domain $Domain) {
                Write-Host "✅ DNS successfully resolves to this server!" -ForegroundColor Green
                break
            } else {
                if ($i -lt 10) {
                    Write-Host "⚠️ DNS not ready yet — retrying in 30 seconds..." -ForegroundColor Yellow
                    Start-Sleep -Seconds 30
                } else {
                    Write-Host "❌ DNS still not pointing to this server after 10 attempts. Exiting." -ForegroundColor Red
                    return
                }
            }
        }
    } else {
        if (-not (Test-SiteForgeDNS -Domain $Domain)) {
            Write-Host "`n⚠️ DNS is not yet pointing to this server." -ForegroundColor Yellow
            Write-Host " Please update your A record and rerun Install-SiteForgeProject." -ForegroundColor DarkGray
            return
        }
    }

    # --- Step 1: Force reinstall logic ---
    if ($ForceReinstall) {
        Write-Host "`n⚠️ Force reinstall mode activated for $Domain" -ForegroundColor Yellow
        $confirm = Read-Host "This will delete NGINX config, SSL certs, site files, and SiteForge vars. Proceed? (y/N)"
        if ($confirm.Trim().ToLower() -notin @('y','yes')) { Write-Host "❌ Operation cancelled."; return }

        Write-Host "`n🧹 Cleaning up old configuration..." -ForegroundColor Yellow
        try {
            sudo systemctl stop nginx *> $null 2>&1
            sudo rm -f "/etc/nginx/sites-available/$Domain" "/etc/nginx/sites-enabled/$Domain" *> $null 2>&1
            sudo rm -rf "/etc/letsencrypt/live/$Domain" "/etc/letsencrypt/renewal/$Domain.conf" "/var/www/html/*" *> $null 2>&1

            $sshConfirm = Read-Host "Do you also want to delete your SSH key (~/.ssh/id_ed25519)? (y/N)"
            if ($sshConfirm.Trim().ToLower() -in @('y','yes')) {
                sudo rm -f ~/.ssh/id_ed25519 ~/.ssh/id_ed25519.pub *> $null 2>&1
                Write-Host "🗝️ SSH keys deleted."
            }

            sudo systemctl start nginx *> $null 2>&1
            Write-Host "✅ Reinstall cleanup complete."
        } catch { Write-Host "⚠️ Cleanup encountered an error: $_" -ForegroundColor Red }
    }

    # --- Step 1.9: Preflight dpkg/apt repair ---
    Write-Host "`n🧰 Checking package manager health..." -ForegroundColor Yellow
    $dpkgLock = (bash -c "sudo fuser /var/lib/dpkg/lock" 2>&1)
    if ($dpkgLock) {
        Write-Host "⚠️ dpkg is locked by another process. Waiting 10 seconds..." -ForegroundColor Yellow
        Start-Sleep -Seconds 10
    }
    bash -c "sudo dpkg --configure -a" 2>&1 | Out-Null
    bash -c "sudo apt-get install -f -y" 2>&1 | Out-Null
    Write-Host "✅ Package manager ready." -ForegroundColor Green

    # --- Step 2: Install dependencies ---
    Write-Host "`n📦 Installing required packages..." -ForegroundColor Yellow

    $packages = "nginx git curl software-properties-common certbot python3-certbot-nginx fail2ban"
    $steps = @(
        @{ cmd = "apt-get update -y -q"; msg = "Updating package lists..." },
        @{ cmd = "apt-get upgrade -y -q"; msg = "Upgrading existing packages..." },
        @{ cmd = "apt-get install -y -q $packages"; msg = "Installing dependencies..." }
    )

    foreach ($step in $steps) {
        Write-Host (" → " + $step.msg) -ForegroundColor DarkGray
        bash -c "sudo DEBIAN_FRONTEND=noninteractive $($step.cmd)" 2>&1 | Out-Null
    }

    # Verify installations
    $check = @{
        "nginx"           = "NGINX web server"
        "git"             = "Git version control"
        "certbot"         = "Let's Encrypt Certbot"
        "fail2ban-client" = "Fail2Ban"
    }

    foreach ($cmd in $check.Keys) {
        if (Get-Command $cmd -ErrorAction SilentlyContinue) {
            Write-Host ("✅ " + $check[$cmd] + " installed") -ForegroundColor Green
        } else {
            Write-Host ("🟥 " + $check[$cmd] + " missing — attempting reinstall...") -ForegroundColor Red
            bash -c "sudo apt-get install -y -q $cmd" 2>&1 | Out-Null
        }
    }

    # --- Step 3: SSH key generation (if needed) ---
    if ($UseSSH) {
        if (-not (Test-Path -Path ~/.ssh/id_ed25519)) {
            Write-Host "`n🔑 Generating new SSH key..."
            ssh-keygen -t ed25519 -C $Email -f ~/.ssh/id_ed25519
            Write-Host "`n📋 Public SSH key (add to GitHub Deploy Keys):" -ForegroundColor Yellow
            cat ~/.ssh/id_ed25519.pub
            Read-Host "`nPress Enter once you've added the key to GitHub"
        } else { Write-Host "✅ SSH key already exists — skipping generation." }
    } else { Write-Host "🔓 Skipping SSH key generation (public repo)." }

    # --- Step 3.5: Optional Security Hardening ---
    $fwChoice = Read-Host "Would you like to enable and lock down the firewall to ports 22, 80, and 443? (Y/n)"
    if ($fwChoice.Trim().ToLower() -notin @('n','no')) {
        Write-Host "`n🛡️ Enabling firewall..." -ForegroundColor Yellow
        Enable-Firewall *> $null 2>&1
    }

    $banChoice = Read-Host "Would you like to install and enable Fail2Ban for brute-force protection? (Y/n)"
    if ($banChoice.Trim().ToLower() -notin @('n','no')) {
        Write-Host "`n🚨 Installing Fail2Ban..." -ForegroundColor Yellow
        Enable-Fail2Ban *> $null 2>&1
    }

    # --- Step 4: Ensure PowerShell profile exists ---
    if (-not (Test-Path -Path $PROFILE)) {
        Write-Host "Creating PowerShell profile..."
        $profileDir = Split-Path -Parent $PROFILE
        if (-not (Test-Path -Path $profileDir)) { New-Item -ItemType Directory -Path $profileDir -Force *> $null 2>&1 }
        New-Item -ItemType File -Path $PROFILE -Force *> $null 2>&1
    }

    # --- Step 5: Persist variables + helper functions ---
    $varsBlock = @"
# SiteForge Variables
`$gitRepo = '$Repo'
`$webDomain = '$Domain'
`$emailAddr = '$Email'
Import-Module SiteForge -Force
"@


    $helpers = @'
# --- SiteForge Helper Functions ---
function errorLogs { sudo tail -f /var/log/nginx/error.log }
function nginxConfig { sudo nano "/etc/nginx/sites-available/$webDomain" }
function catnginxConfig{ sudo cat "/etc/nginx/sites-available/$webDomain" }
function restartNginx { sudo nginx -t && sudo systemctl reload nginx }
'@


    $content = Get-Content $PROFILE -Raw
    $content = $content -replace '(?s)# SiteForge Variables.*?(?=# ---|$)', ''
    $content += "`n$varsBlock`n$helpers"
    Set-Content -Path $PROFILE -Value $content
    Start-Sleep -Seconds 1
    . $PROFILE

    # --- Step 6: Deploy initial site ---
    Write-Host "`n🌍 Deploying website for $Domain..." -ForegroundColor Cyan
    $webRoot = "/var/www/html"
    sudo mkdir -p $webRoot *> $null 2>&1
    cd /root/
    git clone $Repo tempdir | Out-Host

    if (Test-Path "./tempdir/html") {
        Get-ChildItem "./tempdir/html" -Recurse | Move-Item -Destination $webRoot -Force
    } else {
        Get-ChildItem "./tempdir" -Recurse -Exclude '.git','README.md' | Move-Item -Destination $webRoot -Force
    }
    Remove-Item -Recurse -Force ./tempdir *> $null 2>&1

    # --- Step 7: Create NGINX config ---
    $configPath = "/etc/nginx/sites-available/$Domain"
    if (-not (Test-Path $configPath)) {
        Write-Host "`n⚙️ Creating NGINX configuration..." -ForegroundColor Yellow
        $nginxConfig = @'
server {
    listen 80;
    server_name DOMAIN_PLACEHOLDER www.DOMAIN_PLACEHOLDER;
    root /var/www/html;
    index index.html index.htm index.php;
 
    location / {
        try_files $uri $uri/ /index.html;
    }
}
'@
 -replace 'DOMAIN_PLACEHOLDER', $Domain
        $nginxConfig | sudo tee $configPath > $null
        sudo ln -sf $configPath "/etc/nginx/sites-enabled/$Domain" *> $null 2>&1
    }

    # --- Step 8: Obtain SSL cert ---
    Write-Host "`n🔐 Requesting Let's Encrypt SSL certificate..." -ForegroundColor Yellow
    sudo nginx -t *> $null 2>&1
    sudo certbot --nginx --non-interactive --agree-tos --email $Email -d $Domain -d "www.$Domain" *> $null 2>&1

    # --- Step 9: Reload NGINX ---
    sudo nginx -t *> $null 2>&1
    sudo systemctl reload nginx *> $null 2>&1

    # --- Step 10: Success summary ---
    Write-Host "`n✅ SiteForge setup complete!" -ForegroundColor Green
    Write-Host "🌐 Website: https://$Domain"
    Write-Host "📂 Web root: /var/www/html"
    Write-Host "🧩 Config: /etc/nginx/sites-available/$Domain"
    Write-Host "💾 Repo: $Repo"
    Write-Host "`nRun 'update-Website' anytime to redeploy from Git." -ForegroundColor Cyan

    # --- Step 11: Reload profile & status ---
    Write-Host "`n🔄 Reloading PowerShell profile..." -ForegroundColor Yellow
    Start-Sleep -Seconds 2
    & pwsh -NoLogo -Command ". $PROFILE; Get-SiteForgeStatus"
    exit
}