# Hard-coded deploy settings. Fill these in before running.
$FtpHost       = "xTr1m.com"
$FtpUser       = "xTr1m"
$Password   = $null  # prompted at runtime
$RemoteDir     = "/httpdocs/picknplay"
$ProjectPath   = "..\\GameList.csproj"
$Configuration = "Release"
$Runtime       = "win-x64"
$PublishDir    = "$env:TEMP\\GameList-publish"
$SelfContained = $false
$WinScpPath    = "C:\\Users\\frank\\AppData\\Local\\Programs\\WinSCP\\WinSCP.com"
$RecycleAppPool      = $true
$AppPoolName         = "xTr1m.com(domain)(4.0)(pool)"
$WinRmComputer       = "xTr1m.com"
$WinRmCredentialUser = "Administrator"
$UseWinRmHttps       = $true   # set false if using HTTP + TrustedHosts

<#!
.SYNOPSIS
    Publish the app and mirror the output to an FTP-deployed IIS site.

.DESCRIPTION
    - Builds with dotnet publish.
    - Uses WinSCP (ftp) to mirror publish output into $RemoteDir (deletes extraneous remote files).
    - Optionally recycles the IIS app pool remotely via WinRM (no RDP needed).

.PREREQS
    - WinSCP.com available in PATH or set $WinScpPath.
    - FTP user must have write/delete rights to $RemoteDir.
    - WinRM must be enabled for remote app pool recycle (set $RecycleAppPool = $false otherwise).

.EXAMPLE
    pwsh ./scripts/deploy-ftp.ps1
#>

Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"

function Assert-Tool {
    param([string]$Name)
    if (-not (Get-Command $Name -ErrorAction SilentlyContinue)) {
        throw "Required tool '$Name' not found. Install it or update paths."
    }
}

Assert-Tool "dotnet"
Assert-Tool $WinScpPath

function Read-PlainOrPrompt([object]$Value, [string]$Prompt, [bool]$Secure = $false) {
    if ($Value -is [string] -and -not [string]::IsNullOrWhiteSpace($Value)) { return $Value }
    if ($Secure) {
        $pwd = Read-Host -Prompt $Prompt -AsSecureString
        $ptr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($pwd)
        try { return [Runtime.InteropServices.Marshal]::PtrToStringUni($ptr) }
        finally {
            if ($ptr -ne [IntPtr]::Zero) { [Runtime.InteropServices.Marshal]::ZeroFreeBSTR($ptr) }
        }
    }
    return Read-Host -Prompt $Prompt
}

$Password         = Read-PlainOrPrompt $Password "Password" $true
$WinRmAuth        = "Basic"  # Basic for local admin over HTTPS; use Default/Kerberos if joined to domain

Write-Host "1) Publishing..." -ForegroundColor Cyan
if (Test-Path $PublishDir) { Remove-Item $PublishDir -Recurse -Force -ErrorAction SilentlyContinue }
New-Item -ItemType Directory -Force -Path $PublishDir | Out-Null
$publishArgs = @("publish", $ProjectPath, "-c", $Configuration, "-r", $Runtime, "-o", $PublishDir)
if (-not $SelfContained) { $publishArgs += "--self-contained=false" }
dotnet @publishArgs

if ($RecycleAppPool) {
    Write-Host "2) Stopping IIS app pool via WinRM..." -ForegroundColor Cyan
    $sec = ConvertTo-SecureString $Password -AsPlainText -Force
    $cred = New-Object pscredential($WinRmCredentialUser, $sec)
    $invokeParams = @{
        ComputerName = $WinRmComputer
        Credential   = $cred
        ScriptBlock  = {
            Import-Module WebAdministration
            Stop-WebAppPool -Name $using:AppPoolName -ErrorAction SilentlyContinue
        }
    }
    if ($UseWinRmHttps) { $invokeParams["UseSSL"] = $true }
    if ($WinRmAuth)     { $invokeParams["Authentication"] = $WinRmAuth }
    try {
        Invoke-Command @invokeParams
    } catch {
        Write-Warning "WinRM stop failed: $($_.Exception.Message)."
    }
}

Write-Host "3) Syncing via WinSCP (FTP mirror with delete)..." -ForegroundColor Cyan
$tempScript = New-TemporaryFile
@"
option batch continue
option confirm off
open ftp://$($FtpUser):$($Password.Replace('`n','').Replace('`r',''))@$FtpHost
lcd $PublishDir
cd $RemoteDir
synchronize remote . -delete -filemask="|web.config;App_Data/;logs/"
exit
"@ | Set-Content -Path $tempScript -Encoding UTF8

& $WinScpPath "/ini=nul" "/script=$tempScript"
Remove-Item $tempScript -ErrorAction SilentlyContinue

if ($RecycleAppPool) {
    Write-Host "4) Starting IIS app pool via WinRM..." -ForegroundColor Cyan
    $sec = ConvertTo-SecureString $Password -AsPlainText -Force
    $cred = New-Object pscredential($WinRmCredentialUser, $sec)
    $invokeParams = @{
        ComputerName = $WinRmComputer
        Credential   = $cred
        ScriptBlock  = {
            Import-Module WebAdministration
            Start-WebAppPool -Name $using:AppPoolName
        }
    }
    if ($UseWinRmHttps) { $invokeParams["UseSSL"] = $true }
    if ($WinRmAuth)     { $invokeParams["Authentication"] = $WinRmAuth }
    try {
        Invoke-Command @invokeParams
    } catch {
        Write-Warning "WinRM start failed: $($_.Exception.Message)."
    }
}

Write-Host "Done." -ForegroundColor Green
