#!/usr/bin/env bash
# ============================================================================
# One-line installer for the PowerData IPTV streaming-server.
#
# Usage:
#   curl -fsSL https://store.powerdata.dk/install/streaming.sh | bash -s -- VERSION
#
# What it does:
#   1. Verifies docker + docker compose available
#   2. Downloads + verifies the customer tarball + sha256
#   3. Validates the download is actually a gzip (not an HTML 404)
#   4. Untars to ~/iptv-streaming/
#   5. Hands off to the in-tarball install.sh which:
#      - asks license_key, public_url, ports, admin email + password
#      - generates fresh DB password + crypto secrets
#      - builds + starts the stack
#      - prints final URLs + next-steps checklist
# ============================================================================

set -euo pipefail

VERSION="${1:-latest}"
INSTALL_DIR="${INSTALL_DIR:-$HOME/iptv-streaming}"
DOWNLOAD_BASE="${DOWNLOAD_BASE:-https://store.powerdata.dk/dist}"

echo "═══════════════════════════════════════════════════════════════════"
echo "  PowerData IPTV streaming-server installer (v$VERSION)"
echo "═══════════════════════════════════════════════════════════════════"

# ─── Prerequisites ───────────────────────────────────────────────────────────

need() { command -v "$1" >/dev/null || { echo "Missing: $1 — install it first" >&2; exit 1; } ; }
need curl
need openssl
need tar

# auto_install_docker: install docker-ce + compose plugin from Docker's official
# apt repo. Idempotent — re-runs are safe (apt skips already-installed packages).
# Skipped if SKIP_DOCKER_AUTO=1 or if running non-interactive without root.
auto_install_docker() {
    if [ "${SKIP_DOCKER_AUTO:-0}" = "1" ]; then
        echo "SKIP_DOCKER_AUTO=1 set — skipping auto-install" >&2
        return 1
    fi
    if [ "$(id -u)" != "0" ] && ! sudo -n true 2>/dev/null; then
        echo "Auto-install requires root (or passwordless sudo). Re-run as root." >&2
        return 1
    fi
    SUDO=""
    [ "$(id -u)" = "0" ] || SUDO="sudo"

    echo
    echo "Installing Docker Engine + compose plugin from get.docker.com ..."
    if ! curl -fsSL https://get.docker.com -o /tmp/get-docker.sh; then
        echo "FATAL: could not download get-docker.sh" >&2
        return 1
    fi
    if ! $SUDO sh /tmp/get-docker.sh; then
        echo "FATAL: get-docker.sh failed" >&2
        return 1
    fi
    rm -f /tmp/get-docker.sh
    $SUDO systemctl enable --now docker || true
    return 0
}

if ! command -v docker >/dev/null 2>&1 || ! docker compose version >/dev/null 2>&1; then
    echo "Docker (with compose plugin) is not installed."
    if auto_install_docker; then
        if ! docker compose version >/dev/null 2>&1; then
            echo "FATAL: Docker installed but 'docker compose' still not available." >&2
            echo "       Try logging out and back in, or run: systemctl restart docker" >&2
            exit 1
        fi
        echo "Docker installed:"
        docker --version
        docker compose version
    else
        echo "" >&2
        echo "Manual install (Debian/Ubuntu):" >&2
        echo "  curl -fsSL https://get.docker.com | sh" >&2
        echo "  systemctl enable --now docker" >&2
        echo "" >&2
        echo "Then re-run this installer." >&2
        exit 1
    fi
fi

# Refuse to run without enough disk (need ~3 GB for build + images).
FREE_KB=$(df -k "$HOME" | awk 'NR==2 {print $4}')
if [ "${FREE_KB:-0}" -lt 3000000 ]; then
    echo "Not enough free disk on \$HOME (need ~3 GB free, have $((FREE_KB/1024/1024)) GB)" >&2
    exit 1
fi

# ─── Download tarball ────────────────────────────────────────────────────────

mkdir -p "$INSTALL_DIR"
cd "$INSTALL_DIR"

# Compiled mode: pull `iptv-streaming-VERSION-compiled.tar.gz` instead of
# the source bundle. The compiled tarball is ~300 MB (vs ~440 KB source)
# but skips the 5-10 min Docker build on the operator host because the
# Nuitka-compiled streaming image is pre-baked. Operator-set: `COMPILED=1`.
if [ "${COMPILED:-0}" = "1" ]; then
    TARBALL="iptv-streaming-$VERSION-compiled.tar.gz"
    echo "  i compiled mode: pulling pre-built image bundle"
else
    TARBALL="iptv-streaming-$VERSION.tar.gz"
fi
echo
echo "[1/4] Downloading $TARBALL from $DOWNLOAD_BASE/ ..."
if ! curl -fsSL --connect-timeout 10 -o "$TARBALL" "$DOWNLOAD_BASE/$TARBALL"; then
    echo "FATAL: download failed (HTTP error or DNS issue)" >&2
    echo "       Tried: $DOWNLOAD_BASE/$TARBALL" >&2
    exit 2
fi

# Validate it's actually a gzip — common failure mode is a 404 HTML response
# with curl's -fL still happily writing the file.
if ! file "$TARBALL" 2>/dev/null | grep -qi 'gzip compressed'; then
    if command -v file >/dev/null; then
        ACTUAL=$(file "$TARBALL")
    else
        # Detect HTML by leading bytes
        if head -c 100 "$TARBALL" | grep -qi '<!doctype\|<html'; then
            ACTUAL="HTML (likely a 404 page)"
        else
            ACTUAL="not a gzip ($(head -c 4 "$TARBALL" | xxd -p 2>/dev/null || echo unknown))"
        fi
    fi
    echo "FATAL: downloaded file is not a gzip tarball — got $ACTUAL" >&2
    echo "       Likely cause: $DOWNLOAD_BASE/ doesn't host this version" >&2
    rm -f "$TARBALL"
    exit 3
fi

echo "[2/4] Verifying SHA-256..."
if curl -fsSL --connect-timeout 10 -o "$TARBALL.sha256" "$DOWNLOAD_BASE/$TARBALL.sha256"; then
    if ! sha256sum -c "$TARBALL.sha256" >/dev/null 2>&1; then
        echo "FATAL: checksum mismatch — corrupt download or tampering" >&2
        rm -f "$TARBALL" "$TARBALL.sha256"
        exit 4
    fi
    echo "  ✓ checksum OK"
else
    echo "  ! could not fetch .sha256 (skipping verification)" >&2
fi

# ─── Extract ─────────────────────────────────────────────────────────────────

echo "[3/4] Extracting..."
EXTRACT_DIR=$(mktemp -d -p .)
tar -xzf "$TARBALL" -C "$EXTRACT_DIR"

# Tarball top-level: build-streaming-<version>/
INNER=$(find "$EXTRACT_DIR" -maxdepth 1 -mindepth 1 -type d -name 'build-streaming-*' | head -1)
if [ -z "$INNER" ]; then
    echo "FATAL: tarball missing build-streaming-* directory" >&2
    ls "$EXTRACT_DIR" >&2
    exit 5
fi

# Sync contents into INSTALL_DIR — overwriting any existing files. Plain
# `mv` fails on existing non-empty subdirs (docs/, services/, etc.) which
# silently left old code in place on upgrades. Use cp -af which descends
# into existing dirs and overwrites file-by-file.
#
# We DO NOT touch .env or DB volumes — those live alongside, not under
# any of the dirs we're replacing.
cp -af "$INNER/." . 2>&1 | tail -5 || true
rm -rf "$EXTRACT_DIR"

# Sanity check: required files present?
for required in docker-compose.yml install.sh license-public.pem .env.example; do
    if [ ! -e "$required" ]; then
        echo "FATAL: tarball is incomplete — missing $required" >&2
        exit 6
    fi
done
echo "  ✓ tarball extracted, all required files present"

# ─── Hand off to in-tarball install.sh ───────────────────────────────────────

echo "[4/4] Running interactive setup..."
echo
chmod +x install.sh
# Pass our $VERSION through so the in-tarball install.sh can pin
# STREAMING_VERSION=<actual> in .env (otherwise it defaults to "latest"
# which makes the heartbeat banner stick after upgrade).
VERSION="$VERSION" ./install.sh

# ─── Done ────────────────────────────────────────────────────────────────────
# install.sh prints its own success banner; nothing more to add here.
