Param (
  [Parameter()]
  [System.IO.DirectoryInfo]$Directory
)

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
# $ErrorActionPreference alone does not apply to native commands: gpg only sets $LASTEXITCODE, so
# without this a failed signature check would still reach the extraction at the end and the script
# would exit 0. Requires PowerShell 7.3+.
$PSNativeCommandUseErrorActionPreference = $true

if (!$Directory)
{
  $Directory = $PSScriptRoot
}

function Assert-Hash
{
  param
  (
    [Parameter(Mandatory=$true, HelpMessage='The artifact to check.')]
    [System.IO.FileInfo]$File
  )

  $HashFile = "$($File.FullName).sha512"
  if (!(Test-Path $HashFile))
  {
    throw "$($File.Name): no $($File.Name).sha512 to check it against"
  }

  $Hash = (@(Get-Content $HashFile)[0] -split '\s+')[0].Trim().ToUpperInvariant()
  $ComputedHash = (Get-FileHash -Algorithm 'SHA512' $File.FullName).Hash.ToUpperInvariant()
  if ($Hash -ne $ComputedHash)
  {
    throw "$($File.Name): SHA-512 mismatch, read $Hash but computed $ComputedHash"
  }

  "$($File.Name): hash ok"
}

# Everything that is not a hash, a signature or the key file has to be covered by both. Driving the
# checks from the artifacts, rather than from the .sha512 and .asc files that happen to be present,
# is what turns a missing signature into a failure instead of one loop iteration fewer.
$Artifacts = @(Get-ChildItem $Directory -File |
  Where-Object { $_.Extension -notin '.asc', '.sha512' -and $_.Name -ne 'KEYS' })

if ($Artifacts.Count -eq 0)
{
  throw "No artifacts to verify in $Directory"
}

foreach ($Artifact in $Artifacts)
{
  Assert-Hash $Artifact
}

Invoke-WebRequest https://downloads.apache.org/logging/KEYS -OutFile $Directory/KEYS

# A key ring of its own, holding only the downloaded KEYS. Importing into the default key ring
# would accept a signature from any key this machine already has, not only from a key in the
# Logging Services KEYS file.
$KeyringDirectory = New-Item -ItemType Directory -Path (Join-Path ([System.IO.Path]::GetTempPath()) ([guid]::NewGuid()))
try
{
  $Keyring = Join-Path $KeyringDirectory 'logging-keys.gpg'
  gpg --no-default-keyring --keyring $Keyring --batch --quiet --import $Directory/KEYS

  foreach ($Artifact in $Artifacts)
  {
    $Signature = "$($Artifact.FullName).asc"
    if (!(Test-Path $Signature))
    {
      throw "$($Artifact.Name): no $($Artifact.Name).asc to verify it with"
    }

    gpg --no-default-keyring --keyring $Keyring --batch --verify $Signature $Artifact.FullName
    "$($Artifact.Name): signature ok"
  }
}
finally
{
  Remove-Item $KeyringDirectory -Recurse -Force -ErrorAction SilentlyContinue
}

Expand-Archive $Directory/*source*.zip -DestinationPath $Directory/src
pushd "$Directory/src/"
