#!/bin/sh
# build.sh — Mountaineer top-level build entry point.
#
# What it does (in order):
#   1. Build the apkovl tarball from apkovl-src/.
#   2. If running on an Alpine host with the build tools present, invoke
#      mkimage with the Mountaineer Server profile and the apkovl from
#      step 1.
#   3. If not on Alpine (or tools missing), print the canonical podman
#      invocation that runs this same script inside an Alpine container.
#      Mountaineer does not try to be clever and auto-launch the container
#      — the operator chooses to run it themselves.
#
# Build environments documented in BUILD-TOOLS.md.

set -eu

here() { cd "$(dirname "$0")" && pwd; }
ROOT="$(here)"
PROFILE="${PROFILE:-server}"
APORTS="${APORTS:-$ROOT/.aports}"
OUTDIR="${OUTDIR:-$ROOT/out}"

mkdir -p "$OUTDIR"

# --- step 1: standalone target apkovl ------------------------------------
# Build the *target* apkovl as a standalone artifact in out/. This is the
# apkovl an operator would use to fleet-provision an already-installed
# Mountaineer host (drop it in /var/lib/mountaineer/ and reboot, or
# similar). The *live* apkovl (with installer + target embedded) is built
# by mkimage's genapkovl-mountaineer-server.sh in step 2.
echo "==> building target apkovl"
"$ROOT/tools/build-apkovl.sh" server-target

# --- step 2: detect build environment -----------------------------------
on_alpine() {
    [ -f /etc/alpine-release ]
}

have_tool() {
    command -v "$1" >/dev/null 2>&1
}

if ! on_alpine; then
    cat <<EOF

Not running on Alpine — stopping after the apkovl build.

The apkovl is at:
    $APKOVL

To build the ISO, run this script inside an Alpine container with the
build tools mounted in. Canonical invocation:

    podman run --rm -it --privileged \\
        -v $ROOT:/build \\
        -w /build \\
        docker.io/alpine:edge \\
        sh -c 'apk add alpine-sdk abuild xorriso squashfs-tools mkinitfs grub-efi git && ./build.sh'

Or on an Alpine host directly:

    apk add alpine-sdk abuild xorriso squashfs-tools mkinitfs grub-efi git
    ./build.sh

EOF
    exit 0
fi

# On Alpine — verify tools and aports checkout exist.
missing=
for tool in abuild xorriso mksquashfs mkinitfs; do
    have_tool "$tool" || missing="$missing $tool"
done
if [ -n "$missing" ]; then
    echo "error: missing tools on this Alpine host:$missing" >&2
    echo "       apk add alpine-sdk abuild xorriso squashfs-tools mkinitfs" >&2
    exit 1
fi

if [ ! -d "$APORTS" ]; then
    echo "==> cloning aports into $APORTS (shallow)"
    git clone --depth 1 https://gitlab.alpinelinux.org/alpine/aports.git "$APORTS"
fi

# Stage the Mountaineer mkimg profile + genapkovl script into the aports tree.
# mkimage looks up profiles by `profile_$NAME` shell function, so the name
# must be a valid shell identifier — underscore, not hyphen.
cp "$ROOT/mkimg/mkimg.mountaineer_server.sh" "$APORTS/scripts/"
cp "$ROOT/mkimg/genapkovl-mountaineer-server.sh" "$APORTS/scripts/"
chmod +x "$APORTS/scripts/genapkovl-mountaineer-server.sh"

# mkimage's apkovl section caches output in .work/apkovl_<profile>/ keyed
# only by section name — it does NOT incorporate the genapkovl script's
# content hash (unlike most other sections). So if apkovl-src/ changes,
# mkimage silently reuses the previous apkovl. Workaround: blow away the
# apkovl section dir on every build, plus the downstream image section
# (the ISO embeds the apkovl, so it must be re-assembled too).
WORKDIR="$ROOT/.work"
rm -rf "$WORKDIR"/apkovl_* "$WORKDIR"/image-*

# --- step 3: mkimage -----------------------------------------------------
echo "==> running mkimage (this takes a while)"
cd "$APORTS"
export MOUNTAINEER_SRC="$ROOT"
sh scripts/mkimage.sh \
    --tag v3.23 \
    --outdir "$OUTDIR" \
    --arch x86_64 \
    --profile mountaineer_server \
    --workdir "$ROOT/.work" \
    --repository https://dl-cdn.alpinelinux.org/alpine/v3.23/main \
    --repository https://dl-cdn.alpinelinux.org/alpine/v3.23/community

echo "==> done"
ls -lh "$OUTDIR"/*.iso 2>/dev/null || echo "(no ISO produced — check mkimage output above)"
