#!/bin/sh
# colibri-live-rebuild — rebuild and redeploy Colibri on a running live USB.
#
# Automates docs/LIVE-COLIBRI-REBUILD.md so a booted operator USB can rebuild the
# control plane from source in one command — field repair/validation without a
# full ISO rebuild. FreeBSD live image only; privileged steps go through `mdo`
# (the live image has no sudo). It does NOT replace the release ISO process.
#
# Usage:
#   colibri-live-rebuild                 # rebuild from the build checkout's current HEAD
#   colibri-live-rebuild --ref main      # check out a branch/tag/commit first
#   colibri-live-rebuild --build-dir DIR # use an alternate build checkout
set -eu

REF=""
BUILD_DIR="/home/clawdie/ai/colibri-build"
SEED_SRC="/home/clawdie/ai/colibri" # git-backed source staged on the image
REMOTE="https://code.smilepowered.org/clawdie/colibri.git"
BINS="colibri-daemon colibri colibri-mcp colibri-tui"
if [ "${COLIBRI_STAGE_TEST_AGENT:-NO}" = "YES" ]; then
  BINS="${BINS} colibri-test-agent"
fi

usage() { echo "usage: colibri-live-rebuild [--ref <branch|commit>] [--build-dir <path>]"; exit "${1:-0}"; }
while [ $# -gt 0 ]; do
    case "$1" in
        --ref) REF="${2:?--ref needs a value}"; shift 2 ;;
        --build-dir) BUILD_DIR="${2:?--build-dir needs a value}"; shift 2 ;;
        -h|--help) usage 0 ;;
        *) echo "unknown argument: $1" >&2; usage 1 ;;
    esac
done

command -v cargo >/dev/null 2>&1 || { echo "ERROR: cargo not found — pkg install rust" >&2; exit 1; }
command -v git   >/dev/null 2>&1 || { echo "ERROR: git not found — pkg install git" >&2; exit 1; }
command -v mdo   >/dev/null 2>&1 || { echo "ERROR: mdo not found — this targets the FreeBSD live image" >&2; exit 1; }

# 1. Obtain/refresh a working build checkout (kept separate from the shipped
#    read-only source at SEED_SRC). Clone from the on-image source when present
#    so a first rebuild works offline; otherwise from Forgejo.
if [ ! -d "${BUILD_DIR}/.git" ]; then
    if [ -d "${SEED_SRC}/.git" ]; then
        echo "==> cloning build checkout from staged source ${SEED_SRC}"
        git clone "file://${SEED_SRC}" "${BUILD_DIR}"
        git -C "${BUILD_DIR}" remote set-url origin "${REMOTE}" || true
    else
        echo "==> cloning build checkout from ${REMOTE}"
        git clone "${REMOTE}" "${BUILD_DIR}"
    fi
fi
git -C "${BUILD_DIR}" fetch --prune origin 2>/dev/null || echo "WARN: fetch failed (offline?) — using current checkout"
if [ -n "${REF}" ]; then
    echo "==> checking out ${REF}"
    git -C "${BUILD_DIR}" checkout "${REF}"
    git -C "${BUILD_DIR}" pull --ff-only 2>/dev/null || true
fi

# 2. Build the release binaries.
echo "==> building colibri release binaries (this takes a few minutes)"
( cd "${BUILD_DIR}" && cargo build --release \
    -p colibri-daemon -p colibri-client -p colibri-mcp -p colibri-glasspane-tui )

REL="${BUILD_DIR}/target/release"
for b in ${BINS}; do
    [ -x "${REL}/${b}" ] || { echo "ERROR: expected build output missing: ${REL}/${b}" >&2; exit 1; }
done

# 3. Stop the service and clear stale runtime files.
echo "==> stopping colibri_daemon"
mdo -u root service colibri_daemon stop 2>/dev/null || true
mdo -u root pkill -f colibri-daemon 2>/dev/null || true
mdo -u root rm -f /var/run/colibri/colibri.sock \
    /var/run/colibri/colibri-daemon.pid \
    /var/run/colibri/colibri-daemon-supervisor.pid

# 4. Install binaries + rc.d script.
echo "==> installing binaries + rc.d script"
for b in ${BINS}; do
    mdo -u root install -m 0555 "${REL}/${b}" "/usr/local/bin/${b}"
done
mdo -u root install -m 0555 "${BUILD_DIR}/packaging/freebsd/colibri_daemon.in" \
    /usr/local/etc/rc.d/colibri_daemon
mdo -u root chown -R colibri:colibri /var/run/colibri /var/db/colibri /var/log/colibri 2>/dev/null || true

# 5. Restart and validate.
echo "==> starting colibri_daemon"
mdo -u root service colibri_daemon start
sleep 2
mdo -u root service colibri_daemon status || true
colibri status || { echo "ERROR: 'colibri status' could not reach the socket after restart" >&2; exit 1; }

# 6. Record what was installed.
commit=$(git -C "${BUILD_DIR}" rev-parse HEAD 2>/dev/null || echo unknown)
branch=$(git -C "${BUILD_DIR}" symbolic-ref --short -q HEAD 2>/dev/null || echo detached)
now=$(date -u +%Y-%m-%dT%H:%M:%SZ)
_rec=$(mktemp)
cat > "${_rec}" <<JSON
{
  "repo": "${REMOTE}",
  "branch": "${branch}",
  "commit": "${commit}",
  "installed_at": "${now}",
  "note": "Built and installed on running live USB by colibri-live-rebuild"
}
JSON
mdo -u root install -m 0644 "${_rec}" /var/db/colibri/live-rebuild.json
rm -f "${_rec}"

echo "==> done: colibri ${commit} (${branch}) is live on this USB"
echo "    record: /var/db/colibri/live-rebuild.json"
