#!/bin/bash
#
# tools/build-deb — build a vendora-sbc.deb from the current source tree.
#
# Runs on a build host with dpkg-deb, python3, rsync, awk, sed.
# Produces:    vendora-sbc_<version>_all.deb (+ matching .sha256 sidecar)
# Default out: $HOME/armbian-build/output/deb/
# Override:    DEB_OUTPUT_DIR=<path> tools/build-deb
#
# The .deb is "application only" — services/ + tools/ + packaging/systemd/.
# System-level configs (nftables, dnsmasq, NetworkManager) and pip-managed
# Python libs (FastAPI / uvicorn / gpiod) are NOT included; those stay
# image-managed via image/armbian-build-config/customize-image.sh. The .deb
# is intended for IN-PLACE UPGRADES of an already-imaged Vendora SBC, not
# for greenfield apt installs on a bare Debian box.
#
# Per Phase 8.1 (S17): unsigned. Phase 8.2 layers GPG signing of the apt
# repo metadata + the .deb itself.
#
# Usage:
#   cd ~/vendora_sbc        # or anywhere; paths resolve relative to script
#   ./tools/build-deb
#
# Output ends with the SHA-256 + install command for the operator to copy
# to their notes or paste into a deploy script.

set -euo pipefail

# ---------------------------------------------------------------------------
# Paths + config
# ---------------------------------------------------------------------------

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd -- "$SCRIPT_DIR/.." && pwd)"

DEB_OUTPUT_DIR="${DEB_OUTPUT_DIR:-$HOME/armbian-build/output/deb}"

log() { echo "[vendora-build-deb] $*"; }
die() { echo "[vendora-build-deb] ERROR: $*" >&2; exit 1; }

# ---------------------------------------------------------------------------
# Sanity checks
# ---------------------------------------------------------------------------

command -v dpkg-deb  >/dev/null || die "dpkg-deb not found (apt install -y dpkg)"
command -v rsync     >/dev/null || die "rsync not found (apt install -y rsync)"
command -v python3   >/dev/null || die "python3 not found"

[ -f "$PROJECT_ROOT/services/common/version.py" ] \
    || die "version.py missing — \$PROJECT_ROOT=$PROJECT_ROOT looks wrong"
[ -f "$PROJECT_ROOT/packaging/debian/control.template" ] \
    || die "packaging/debian/control.template missing"
[ -d "$PROJECT_ROOT/packaging/systemd" ] \
    || die "packaging/systemd/ missing"

# ---------------------------------------------------------------------------
# Read version from the canonical source
# ---------------------------------------------------------------------------

VERSION=$(python3 - <<EOF
import re, sys
with open("$PROJECT_ROOT/services/common/version.py") as f:
    for line in f:
        m = re.match(r'\s*SBC_VERSION\s*=\s*"(.+)"', line)
        if m:
            print(m.group(1))
            sys.exit(0)
sys.exit(1)
EOF
)
[ -n "$VERSION" ] || die "could not extract SBC_VERSION from version.py"
log "package version: $VERSION (from services/common/version.py)"

# Debian's version field has strict syntax. Most permissively: upstream
# version chars are [A-Za-z0-9.+~:-]. We don't enforce here; dpkg-deb will
# reject anything invalid downstream.

# ---------------------------------------------------------------------------
# Stage the package contents
# ---------------------------------------------------------------------------

STAGING=$(mktemp -d -t vendora-deb-XXXXXX)
trap 'rm -rf "$STAGING"' EXIT

log "staging at $STAGING"

# DEBIAN/ metadata
mkdir -p "$STAGING/DEBIAN"
sed "s|@@VERSION@@|$VERSION|g" \
    "$PROJECT_ROOT/packaging/debian/control.template" \
    > "$STAGING/DEBIAN/control"

# Maintainer scripts must be 0755 — chmod here so source tree's mode
# doesn't leak (Windows checkouts can come through with 0644).
for script in postinst prerm postrm; do
    cp "$PROJECT_ROOT/packaging/debian/$script" "$STAGING/DEBIAN/$script"
    chmod 0755 "$STAGING/DEBIAN/$script"
done

# /opt/vendora_sbc/ payload
log "  rsync services/ → /opt/vendora_sbc/services/"
mkdir -p "$STAGING/opt/vendora_sbc"
rsync -a \
    --exclude='__pycache__' \
    --exclude='*.pyc' \
    --exclude='.pytest_cache' \
    --exclude='.mypy_cache' \
    --exclude='.venv' \
    --exclude='venv' \
    "$PROJECT_ROOT/services" "$STAGING/opt/vendora_sbc/"

log "  rsync tools/ → /opt/vendora_sbc/tools/"
rsync -a "$PROJECT_ROOT/tools" "$STAGING/opt/vendora_sbc/"

log "  rsync packaging/systemd/ → /opt/vendora_sbc/packaging/systemd/"
mkdir -p "$STAGING/opt/vendora_sbc/packaging"
rsync -a "$PROJECT_ROOT/packaging/systemd" \
    "$STAGING/opt/vendora_sbc/packaging/"

# Show what's about to ship (helps catch accidental inclusions/exclusions)
payload_files=$(find "$STAGING/opt" -type f 2>/dev/null | wc -l)
payload_size=$(du -sh "$STAGING/opt" 2>/dev/null | awk '{print $1}')
log "  staged payload: $payload_files files, $payload_size"

# ---------------------------------------------------------------------------
# Build the .deb
# ---------------------------------------------------------------------------

mkdir -p "$DEB_OUTPUT_DIR"
DEB_PATH="$DEB_OUTPUT_DIR/vendora-sbc_${VERSION}_all.deb"

log "building $DEB_PATH"
# --root-owner-group: force ownership to root:root regardless of the
# build host's effective uid/gid. Important — building as non-root on
# the build VM should still produce a package whose installed files
# end up root-owned on the target.
dpkg-deb --build --root-owner-group "$STAGING" "$DEB_PATH" >/dev/null

# Sidecar sha256 file makes it easy for the apt repo (or operators
# downloading directly) to verify before installing.
sha=$(sha256sum "$DEB_PATH" | awk '{print $1}')
echo "$sha  $(basename "$DEB_PATH")" > "${DEB_PATH%.deb}.sha256"

size=$(du -h "$DEB_PATH" | awk '{print $1}')

# ---------------------------------------------------------------------------
# Report
# ---------------------------------------------------------------------------

log ""
log "DONE."
log "  path:    $DEB_PATH"
log "  size:    $size"
log "  sha256:  $sha"
log ""
log "Install on a target device (image-flashed SBC):"
log "  scp $DEB_PATH vendora-sbc:/tmp/"
log "  ssh vendora-sbc 'sudo apt install -y /tmp/$(basename "$DEB_PATH")'"
log ""
log "Inspect:"
log "  dpkg-deb --info     $DEB_PATH"
log "  dpkg-deb --contents $DEB_PATH"
