#!/usr/bin/env bash
set -Eeuo pipefail
platform="linux"
architecture="x86_64"
if [[ "$(id -u)" -ne 0 ]]; then echo "Run this installer with sudo."; exit 1; fi
if [[ "$(uname -s)" != Linux || "$(uname -m)" != "$architecture" ]]; then echo "This installer requires Ubuntu $architecture."; exit 1; fi
source /etc/os-release
if [[ "${ID:-}" != ubuntu ]]; then echo "Ubuntu is required."; exit 1; fi
case "${VERSION_ID:-}" in 22.04|24.04|26.04) ;; *) echo "Unsupported Ubuntu version."; exit 1 ;; esac
release_url="${1:-}"
version="0.2.26"
product_version="0.2.2"
build="0001"
if [[ "$release_url" != "https://portguard.kamindo.co/downloads/server/$platform/$product_version/build$build/portguard-console-$product_version-build$build.tar.gz" ]]; then
  echo "Supply the matching HTTPS release archive URL from the PortGuard portal."; exit 1
fi
if [[ -e /opt/portguard/current ]]; then echo "GUI updater is already installed. Use Settings -> Updates."; exit 1; fi
apt-get update
DEBIAN_FRONTEND=noninteractive apt-get install -y ca-certificates curl nginx python3 python3-venv
work_dir="$(mktemp -d)"
trap 'rm -rf "$work_dir"' EXIT
curl --fail --silent --show-error --proto '=https' --max-time 600 --max-filesize 209715200 "$release_url" -o "$work_dir/package.tar.gz"
curl --fail --silent --show-error --proto '=https' --max-time 30 --max-filesize 4096 "$release_url.sha256" -o "$work_dir/package.sha256"
python3 - "$work_dir" "$version" <<'PYEXTRACT'
import hashlib,re,sys,tarfile
from pathlib import Path,PurePosixPath
work,version=Path(sys.argv[1]),sys.argv[2]
expected=(work/'package.sha256').read_text().split()[0]
if not re.fullmatch('[0-9a-f]{64}',expected) or hashlib.sha256((work/'package.tar.gz').read_bytes()).hexdigest()!=expected:
    raise SystemExit('Package checksum verification failed')
seen=set();total=0
with tarfile.open(work/'package.tar.gz','r:gz') as tar:
    for member in tar:
        path=PurePosixPath(member.name)
        if path.is_absolute() or '..' in path.parts or not path.parts or path.parts[0]!='portguard-server-'+version or member.name in seen:
            raise SystemExit('Unsafe package path')
        seen.add(member.name)
        if len(seen)>10000: raise SystemExit('Too many package entries')
        target=work.joinpath(*path.parts)
        if member.isdir(): target.mkdir(parents=True,exist_ok=True); continue
        if not member.isfile(): raise SystemExit('Package links and special files are forbidden')
        total+=member.size
        if total>512*1024*1024: raise SystemExit('Package too large')
        target.parent.mkdir(parents=True,exist_ok=True)
        with tar.extractfile(member) as source,target.open('xb') as output:
            while chunk:=source.read(65536): output.write(chunk)
        target.chmod(0o644)
PYEXTRACT
# Bootstrap dependencies are isolated; no recursive chmod touches an installed venv.
python3 -m venv "$work_dir/bootstrap-venv"
"$work_dir/bootstrap-venv/bin/python" -m pip --isolated install --index-url https://pypi.org/simple --disable-pip-version-check --only-binary=:all: cryptography==46.0.5
"$work_dir/bootstrap-venv/bin/python" "$work_dir/portguard-server-$version/updater/bootstrap.py" "$work_dir/portguard-server-$version" "$platform"
