#!/usr/bin/env bash
# Install or update WiFi Vouchers on Ubuntu 24.04 amd64.
# Download this script and run: bash install.sh
set -euo pipefail
fail() { printf '%s\n' "$*" >&2; exit 1; }
if [[ ${1:-} == --help ]]; then
  echo 'Usage: bash install.sh [--help] — install or update WiFi Vouchers on Ubuntu 24.04 amd64.'
  exit 0
fi
[[ $# == 0 ]] || fail 'Unknown argument. Use --help.'
[[ $(uname -s) == Linux ]] || fail 'This installer requires Linux (Ubuntu 24.04 amd64).'
# shellcheck source=/dev/null
source /etc/os-release
[[ ${ID:-} == ubuntu && ${VERSION_ID:-} == 24.04 ]] || fail 'Supported system: Ubuntu 24.04 amd64. See https://getvouchers.app/downloads/linux'
for tool in curl python3 dpkg dpkg-deb sha256sum stat apt-get; do
  command -v "$tool" >/dev/null || fail "Missing $tool. Install prerequisites with: sudo apt install curl python3"
done
[[ $(dpkg --print-architecture) == amd64 ]] || fail 'This release requires amd64 (x86-64); ARM is not supported.'
work=$(mktemp -d)
trap 'rm -rf "$work"' EXIT
curl --fail --silent --show-error --proto '=https' --connect-timeout 20 --max-time 60 \
  https://getvouchers.app/downloads.json -o "$work/catalog.json"
python3 - "$work/catalog.json" > "$work/asset" <<'PY'
import json,re,sys
from urllib.parse import urlsplit
try:
    catalog=json.load(open(sys.argv[1]))
    candidates=[]
    for release in catalog:
        version=release['version']
        if not re.fullmatch(r'\d+\.\d+\.\d+',version): raise ValueError('Invalid version')
        for asset in release['downloads']:
            if asset.get('platform')=='linux' and asset.get('format')=='deb' and asset.get('architecture')=='x64':
                candidates.append((tuple(map(int,version.split('.'))),version,asset))
    if not candidates: raise ValueError('No Linux installer has been published yet')
    _,version,asset=max(candidates,key=lambda x:x[0])
    url=asset['url']; parsed=urlsplit(url)
    if (parsed.scheme!='https' or parsed.netloc not in ('files.fairu.app','fairu.app')
        or parsed.query or parsed.fragment or any(c.isspace() or ord(c)<32 for c in url)):
        raise ValueError('Invalid download URL')
    if asset['filename']!=f'wifi-vouchers-{version}-linux-x64.deb': raise ValueError('Invalid filename')
    if not re.fullmatch('[a-f0-9]{64}',asset['sha256']): raise ValueError('Invalid checksum')
    if type(asset['size']) is not int or not 0<asset['size']<2_000_000_000: raise ValueError('Invalid file size')
    print(version); print(url); print(asset['sha256']); print(asset['size'])
except (ValueError,KeyError,TypeError) as error:
    sys.exit(f'Cannot read the release catalog: {error}')
PY
{ IFS= read -r version; IFS= read -r download_url; IFS= read -r checksum; IFS= read -r size; } < "$work/asset"
installed=$(dpkg-query -W -f='${Status} ${Version}' wifi-vouchers 2>/dev/null || true)
if [[ "$installed" == 'install ok installed '* ]]; then
  installed=${installed#install ok installed }
  if dpkg --compare-versions "$installed" ge "$version"; then
    printf 'WiFi Vouchers %s is installed; no update is needed.\n' "$installed"
    exit 0
  fi
  printf 'Updating WiFi Vouchers from %s to %s. Close the app before continuing.\n' "$installed" "$version"
else
  printf 'Installing WiFi Vouchers %s.\n' "$version"
fi
curl --fail --silent --show-error --proto '=https' --connect-timeout 20 --max-time 600 \
  --max-filesize "$size" "$download_url" -o "$work/wifi-vouchers.deb"
[[ $(stat -c %s "$work/wifi-vouchers.deb") == "$size" ]] || fail 'Download size mismatch; nothing was installed.'
printf '%s  %s\n' "$checksum" "$work/wifi-vouchers.deb" | sha256sum --check --status || fail 'Checksum mismatch; nothing was installed.'
[[ $(dpkg-deb -f "$work/wifi-vouchers.deb" Package) == wifi-vouchers ]] || fail 'Unexpected package name.'
[[ $(dpkg-deb -f "$work/wifi-vouchers.deb" Version) == "$version" ]] || fail 'Unexpected package version.'
[[ $(dpkg-deb -f "$work/wifi-vouchers.deb" Architecture) == amd64 ]] || fail 'Unexpected package architecture.'
elevate=()
if (( EUID != 0 )); then
  command -v sudo >/dev/null || fail 'sudo is required to install the verified package.'
  elevate=(sudo)
fi
"${elevate[@]}" apt-get update
"${elevate[@]}" apt-get install "$work/wifi-vouchers.deb"
printf 'WiFi Vouchers %s is ready. Open it from your application menu or run wifi-vouchers.\n' "$version"
