[CmdletBinding()]
param(
  [string]$RepoRoot = (Split-Path -Parent $PSScriptRoot),
  [string]$IisRoot = 'C:\inetpub\wwwroot',
  [int]$WebsitePort = 4341,
  [int]$AppPort = 4492
)

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

try {
  Import-Module WebAdministration -ErrorAction Stop
} catch {
  throw 'The IIS WebAdministration module is required on the Windows runner.'
}

function Invoke-RoboCopyMirror {
  param(
    [Parameter(Mandatory = $true)]
    [string]$Source,

    [Parameter(Mandatory = $true)]
    [string]$Destination
  )

  if (-not (Test-Path -LiteralPath $Source)) {
    throw "Build output not found: $Source"
  }

  New-Item -ItemType Directory -Path $Destination -Force | Out-Null
  robocopy $Source $Destination /MIR /NFL /NDL /NJH /NJS /NP | Out-Null

  if ($LASTEXITCODE -gt 7) {
    throw "robocopy failed from $Source to $Destination with exit code $LASTEXITCODE"
  }

  $global:LASTEXITCODE = 0
}

function Ensure-AppPool {
  param(
    [Parameter(Mandatory = $true)]
    [string]$Name
  )

  $appPoolPath = "IIS:\AppPools\$Name"

  if (-not (Test-Path -LiteralPath $appPoolPath)) {
    New-WebAppPool -Name $Name | Out-Null
  }

  Set-ItemProperty $appPoolPath -Name managedRuntimeVersion -Value ''
}

function Publish-IisSite {
  param(
    [Parameter(Mandatory = $true)]
    [string]$SiteName,

    [Parameter(Mandatory = $true)]
    [string]$SourcePath,

    [Parameter(Mandatory = $true)]
    [string]$DestinationPath,

    [Parameter(Mandatory = $true)]
    [int]$Port
  )

  Ensure-AppPool -Name $SiteName
  Invoke-RoboCopyMirror -Source $SourcePath -Destination $DestinationPath

  $existingSite = Get-Website -Name $SiteName -ErrorAction SilentlyContinue
  if ($null -ne $existingSite) {
    Stop-Website -Name $SiteName -ErrorAction SilentlyContinue
    Remove-Website -Name $SiteName
  }

  New-Website -Name $SiteName -PhysicalPath $DestinationPath -Port $Port -ApplicationPool $SiteName | Out-Null
  Start-Website -Name $SiteName

  Write-Host "Deployed $SiteName to $DestinationPath on port $Port."
}

$deployments = @(
  @{
    SiteName = 'toju-website'
    SourcePath = (Join-Path $RepoRoot 'website\dist\toju-website')
    DestinationPath = (Join-Path $IisRoot 'toju-website')
    Port = $WebsitePort
  },
  @{
    SiteName = 'toju-app'
    SourcePath = (Join-Path $RepoRoot 'dist\client\browser')
    DestinationPath = (Join-Path $IisRoot 'toju-app')
    Port = $AppPort
  }
)

foreach ($deployment in $deployments) {
  Publish-IisSite @deployment
}

$global:LASTEXITCODE = 0
