#!/usr/bin/env bash
source "$(dirname -- "${BASH_SOURCE[0]}")/lib.sh"
[[ $# == 0 || ( $# == 1 && $1 == --install-deps ) ]] || die 'Usage: tools/bootstrap-host [--install-deps]'
[[ $(uname -s) == Linux && $(uname -m) == x86_64 ]] || die 'M0 requires an x86_64 Linux build host'
source /etc/os-release
[[ $ID == arch ]] || die 'M0 bootstrap supports Arch Linux; see docs/developer/build-host.md'
(( EUID != 0 )) || die 'Run as a normal user, not root'
[[ ! $FDS_ROOT =~ [[:space:]] ]] || die 'xbps-src requires a checkout path without whitespace'
if [[ ${1:-} == --install-deps ]]; then
    sudo pacman -S --needed bash coreutils binutils git curl make file tar xz gzip zstd \
        bubblewrap rustup ca-certificates findutils diffutils grep sed gawk util-linux
fi
for cmd in bash git curl make file readelf ldd tar xz gzip zstd sha256sum bwrap rustup \
    find diff grep sed awk flock install; do
    need "$cmd"
done
# Fail before downloading if unprivileged build containers cannot run.
bwrap --ro-bind / / --unshare-user --uid 0 --gid 0 true || die 'bubblewrap user namespaces are unavailable'
cd "$FDS_ROOT"
mkdir -p out/downloads out/logs .host
if [[ ${FDS_OFFLINE:-0} != 1 ]]; then
    git -c http.lowSpeedLimit=1000 -c http.lowSpeedTime=60 submodule update --init --depth 1 vendor/void-packages
fi
check_void_pin
source config/host-tools.conf
archive="out/downloads/${XBPS_STATIC_URL##*/}"
if [[ ! -f $archive ]]; then
    [[ ${FDS_OFFLINE:-0} != 1 ]] || die "Missing offline XBPS archive: $archive"
    curl -fL --retry 3 --connect-timeout 20 --max-time 900 "$XBPS_STATIC_URL" -o "$archive.part"
    printf '%s  %s\n' "$XBPS_STATIC_SHA256" "$archive.part" | sha256sum -c -
    mv -- "$archive.part" "$archive"
fi
printf '%s  %s\n' "$XBPS_STATIC_SHA256" "$archive" | sha256sum -c -
# Verify the archive even on repeat runs; refresh tools from the verified input.
mkdir -p .host/xbps
tar -xJf "$archive" -C .host/xbps
for cmd in xbps-install xbps-query xbps-create xbps-rindex xbps-uhelper; do
    tools/verify-elf "$FDS_XBPS/$cmd" x86_64 static
    "$FDS_XBPS/$cmd" -V
done
use_xbps
tools/prepare-void
rust_version=$(sed -n 's/^channel = "\([^"]*\)"$/\1/p' rust-toolchain.toml)
[[ $rust_version =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]] || die 'Rust toolchain must be version pinned'
if [[ ${FDS_OFFLINE:-0} == 1 ]]; then
    [[ -f .host/frozen/lock.json ]] || die 'Restore a verified frozen-input snapshot before offline bootstrap'
    rustc --version | grep -q "^rustc $rust_version " || die 'Wrong restored Rust toolchain'
    rustfmt --version
    rustup target list --installed | grep -qx aarch64-unknown-linux-musl || die 'Missing restored ARM Rust target'
else
    rustup toolchain install "$rust_version" --profile minimal --component rustfmt --target aarch64-unknown-linux-musl
fi
# Cargo resolves all workspace members even for the dependency-free smoketest.
# Seed the locked Dasung dependencies so later --offline builds work on a new host.
fetch_rust_inputs
(
    cd "$FDS_VOID"
    xbps_src -A x86_64 binary-bootstrap
) 2>&1 | tee out/logs/xbps-bootstrap.log
[[ $(cat "$FDS_VOID/masterdir-x86_64/.xbps_chroot_init") == x86_64 ]] || die 'Wrong Void build container architecture'
xbps-query -r "$FDS_VOID/masterdir-x86_64" base-chroot >/dev/null
bwrap --ro-bind "$FDS_VOID/masterdir-x86_64" / --dev /dev --proc /proc \
    --chdir / /usr/bin/gcc --version
printf '\nPASS: M0 host bootstrap; run make smoke-test to build both aarch64 artifacts\n'
