#!/usr/bin/env bash
# cli-install.sh                   build the command-line tools and stage them
# cli-install.sh --print-bin-dir   print where they are staged, and exit
#
# Builds the multi-call binary in release mode (`--features cli`, which the
# target requires) and stages it in tmp/cli/bin under every name it answers
# to: `rust-fs-ext4`, the real file, and each dotted name as a relative
# symlink to it -- the layout an install has. The dotted names come from the
# binary itself (`rust-fs-ext4 generate names`), so this script names none.
# The man pages and completions go in tmp/cli/share, beside bin/, where an
# install puts them, and are generated by the binary too.
#
# It prints the PATH line to use. `chore test:cli` tests whatever PATH
# finds, so the staged directory has to come first for it to test these.
#
# CLI_INSTALL_DIR names another prefix (the binaries go in its bin/).
set -euo pipefail

REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd -P)"
PREFIX="${CLI_INSTALL_DIR:-$REPO/tmp/cli}"
BIN="$PREFIX/bin"

if [ "${1:-}" = "--print-bin-dir" ]; then
    printf '%s\n' "$BIN"
    exit 0
fi

cd "$REPO"
cargo build --locked --release --features cli --bin rust-fs-ext4 --quiet
built="${CARGO_TARGET_DIR:-$REPO/target}/release/rust-fs-ext4"
[ -x "$built" ] || { echo "cli-install: cargo built no $built" >&2; exit 1; }

# The prefix may not be ours alone (CLI_INSTALL_DIR=$HOME/.local), so bin/
# and share/ are never cleared: only rust-fs-ext4, its own links and the
# pages and completions it generates are replaced, and a file under one of
# the tool names that is not our link is refused.
SHARE="$PREFIX/share"
names="$("$built" generate names)"
[ -n "$names" ] || { echo "cli-install: the binary lists no tool names" >&2; exit 1; }
for name in $names; do
    link="$BIN/$name"
    if [ -e "$link" ] || [ -L "$link" ]; then
        [ "$(readlink "$link" 2>/dev/null)" = rust-fs-ext4 ] || {
            echo "cli-install: $link exists and is not a link to rust-fs-ext4; not replacing it" >&2
            exit 1
        }
    fi
done
mkdir -p "$BIN" "$SHARE"
cp "$built" "$BIN/rust-fs-ext4.new"
mv -f "$BIN/rust-fs-ext4.new" "$BIN/rust-fs-ext4"
for name in $names; do
    ln -sfn rust-fs-ext4 "$BIN/$name"
done

"$BIN/rust-fs-ext4" generate man "$SHARE" >/dev/null
"$BIN/rust-fs-ext4" generate completions "$SHARE" >/dev/null

echo "cli:install: staged rust-fs-ext4 and $(echo $names | tr ' ' ',') in $BIN"
echo "cli:install: to test or use them, put that directory first on PATH:"
echo "  export PATH=\"$BIN:\$PATH\""
