#!/bin/bash
# ==============================================================================
# Bootstrap instalace RTU
# ==============================================================================
#   curl -fsSL https://rtu-install.apptive.cz | sudo bash
#
# Stáhne balík instalátoru, ověří jeho integritu a spustí průvodce.
# Jednotka se nepřipojuje na GitHub a nepotřebuje žádný SSH klíč — instalátor
# přichází z S3 přes CloudFront, artefakty aplikací z ECR.
#
# Obsah je veřejně čitelný a je to v pořádku: nic tajného tu není. Certifikáty
# i hesla vznikají až na jednotce, AWS přístup si vymění přes IoT credentials
# provider. Podvržení brání kontrolní součet, ne utajení.
#
# Volby (proměnnou prostředí):
#   RTU_VERSION=v1.2.3     konkrétní verze instalátoru (výchozí: latest)
#   RTU_BASE_URL=...       jiný zdroj (testovací distribuce)
#   RTU_NONINTERACTIVE=1   bez otázek, projede vše
# ==============================================================================
set -uo pipefail

# Debian 13 startuje s ANSI_X3.4-1968 (ciste ASCII) — bez UTF-8 se ramecky
# i diakritika rozlozi na jednotlive bajty. C.utf8 je v zakladu vzdy.
if [ "$(locale charmap 2>/dev/null)" != "UTF-8" ]; then
    for L in C.UTF-8 C.utf8; do
        if locale -a 2>/dev/null | grep -qix "${L/UTF-8/utf8}"; then
            export LANG="$L" LC_ALL="$L"
            break
        fi
    done
fi
export TERM="${TERM:-xterm}"

BASE_URL="${RTU_BASE_URL:-https://rtu-install.apptive.cz}"
# Pozor: /etc/os-release definuje VERSION, takže vlastní proměnná musí mít
# jiné jméno — jinak by se po `. /etc/os-release` přepsala na "13 (trixie)"
# a instalátor by stahoval neexistující balík.
RTU_VER="${RTU_VERSION:-latest}"
WORK="/opt/dhrtu/installer"

R=$'\033[31m'; G=$'\033[32m'; Y=$'\033[33m'; C=$'\033[36m'
B=$'\033[1m';  D=$'\033[2m';  N=$'\033[0m'

say()  { printf '  %s\n' "$*"; }
ok()   { printf '  %s%s%s\n' "$G" "$*" "$N"; }
warn() { printf '  %s%s%s\n' "$Y" "$*" "$N"; }
die()  { printf '  %s%s%s\n' "$R" "$*" "$N"; exit 1; }

echo
echo "${C}══════════════════════════════════════════════════════════${N}"
echo "${C}  ${B}RTU installer${N}"
echo "${C}══════════════════════════════════════════════════════════${N}"
echo

# ------------------------------------------------------------- předpoklady ---
[ "$(id -u)" -eq 0 ] || die "Run as root:  curl -fsSL ${BASE_URL} | sudo bash"

for cmd in curl tar sha256sum; do
    command -v "$cmd" >/dev/null 2>&1 || die "Missing ${cmd} - install it: apt install ${cmd}"
done

if [ -r /etc/os-release ]; then
    # V subshellu, ať proměnné z os-release neunikly do skriptu.
    OS_PRETTY=$(. /etc/os-release && echo "$PRETTY_NAME")
    OS_VERSION=$(. /etc/os-release && echo "$VERSION_ID")
    say "System:   ${OS_PRETTY}"
    if [ "${OS_VERSION:-}" != "13" ]; then
        warn "This installer targets Debian 13 (trixie)"
        warn "It may not work on ${OS_PRETTY:-another system}"
    fi
fi

HOST=$(grep '127.0.1.1' /etc/hosts 2>/dev/null | awk '{print $2}')
say "Unit:     ${HOST:-${Y}unknown - no entry in /etc/hosts${N}}"
say "Source:   ${BASE_URL}"
echo

# ---------------------------------------------------------------- konektivita
say "Checking connectivity..."
if ! curl -fsS --max-time 15 -o /dev/null "${BASE_URL}/VERSION" 2>/dev/null; then
    die "${BASE_URL} unreachable - check network and DNS"
fi

# ------------------------------------------------------------------- verze ---
if [ "$RTU_VER" = "latest" ]; then
    RTU_VER=$(curl -fsS --max-time 15 "${BASE_URL}/VERSION" 2>/dev/null | tr -d '[:space:]')
    [ -z "$RTU_VER" ] && die "Cannot determine the current installer version"
fi
say "Version:  ${RTU_VER}"

TARBALL="rtu-installer-${RTU_VER}.tar.gz"
TMP=$(mktemp -d)
trap 'rm -rf "$TMP"' EXIT

# ----------------------------------------------------------------- stažení ---
echo
say "Downloading installer..."
if ! curl -fsSL --max-time 120 -o "${TMP}/${TARBALL}" "${BASE_URL}/${TARBALL}"; then
    die "Download of ${TARBALL} failed"
fi

# Kontrolní součet je povinný. Bez něj by šlo podstrčit cokoli tomu, kdo
# umí odpovědět dřív než CloudFront — a tenhle skript běží jako root.
if ! curl -fsSL --max-time 30 -o "${TMP}/${TARBALL}.sha256" \
     "${BASE_URL}/${TARBALL}.sha256" 2>/dev/null; then
    die "Checksum missing - cannot verify the package, aborting"
fi

EXPECT=$(awk '{print $1}' "${TMP}/${TARBALL}.sha256")
ACTUAL=$(sha256sum "${TMP}/${TARBALL}" | awk '{print $1}')

if [ "$EXPECT" != "$ACTUAL" ]; then
    die "Checksum mismatch - the package is corrupted or tampered with"
fi
ok "Integrity verified"

# Podpis je volitelný: minisign nemusí být na čerstvém systému.
# Když je k dispozici klíč i podpis, ověříme — jinak stačí součet přes HTTPS.
if command -v minisign >/dev/null 2>&1 && \
   curl -fsSL --max-time 15 -o "${TMP}/${TARBALL}.minisig" \
        "${BASE_URL}/${TARBALL}.minisig" 2>/dev/null && \
   curl -fsSL --max-time 15 -o "${TMP}/rtu.pub" "${BASE_URL}/rtu.pub" 2>/dev/null; then
    if minisign -Vm "${TMP}/${TARBALL}" -p "${TMP}/rtu.pub" >/dev/null 2>&1; then
        ok "Signature verified"
    else
        die "Signature mismatch - this package is not ours"
    fi
fi

# --------------------------------------------------------------- rozbalení ---
say "Extracting into ${WORK}"
# Předchozí instalátor přesuneme, ne smažeme — kdyby nový selhal.
if [ -d "$WORK" ]; then
    rm -rf "${WORK}.prev"
    mv "$WORK" "${WORK}.prev"
fi
mkdir -p "$WORK"
tar xzf "${TMP}/${TARBALL}" -C "$WORK" --strip-components=1 \
    || die "Extraction failed"

chmod +x "${WORK}"/dhrtu-install "${WORK}"/dhrtu-setup \
         "${WORK}"/install.sh "${WORK}"/steps/*.sh 2>/dev/null || true

echo "$RTU_VER" > "${WORK}/.version"
ok "Installer ready"

# ----------------------------------------------------------------- spuštění --
echo
if [ "${RTU_NONINTERACTIVE:-0}" = "1" ]; then
    exec "${WORK}/dhrtu-install" --auto
fi

# whiptail dává čitelnější průvodce, ale potřebuje terminál na VŠECH třech
# deskriptorech. Při `curl | bash` je rourou i stdout a stderr — whiptail pak
# kreslí okno do roury, řídicí znaky se sypou do konzole a klávesy nemá odkud
# číst. Průvodce vypadá funkčně, ale nejde ovládat. Připojujeme proto /dev/tty
# i na výstupy, ne jen na stdin.
# Textovy pruvodce, ne whiptail. Pri `curl | bash` je stdin roura a whiptail
# si klavesy ze stdin nacte jako obycejny text - sipky se vypisou jako ^[[C
# misto aby posunuly vyber. Presmerovani /dev/tty to nespravi: whiptail navic
# kresli na stderr a hodnotu vraci na stdout, takze prohazovani deskriptoru
# (3>&1 1>&2 2>&3) se s presmerovanim z bootstrapu bije.
#
# Textovy pruvodce cte pres `read < /dev/tty`, coz funguje i za rourou.
# Whiptail zustava dostupny rucne:  sudo /opt/dhrtu/installer/dhrtu-setup
# Samotna existence /dev/tty nestaci - v kontejneru bez -t soubor existuje,
# ale otevrit ho nelze ("No such device or address"). Testujeme proto otevrenim.
if [ -e /dev/tty ] && (exec 3< /dev/tty) 2>/dev/null; then
    exec "${WORK}/dhrtu-install" < /dev/tty > /dev/tty 2>/dev/tty
else
    warn "No terminal - continuing unattended"
    exec "${WORK}/dhrtu-install" --auto
fi
