#!/usr/bin/env bash
# SPDX-License-Identifier: MIT
set -euo pipefail

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

want_build=0
want_clean="${LAIRU_PREFLIGHT_CLEAN:-0}"
for arg in "$@"; do
  case "$arg" in
    --build) want_build=1 ;;
    --clean) want_clean=1 ;;
    *)
      echo "usage: scripts/debian-trixie-preflight [--build] [--clean]" >&2
      exit 2
      ;;
  esac
done

codename="unknown"
pretty="unknown"
if [ -r /etc/os-release ]; then
  # shellcheck disable=SC1091
  . /etc/os-release
  codename="${VERSION_CODENAME:-unknown}"
  pretty="${PRETTY_NAME:-unknown}"
fi

echo "Host: $pretty"
if [ "$codename" != "trixie" ]; then
  echo "warning: expected Debian trixie, found VERSION_CODENAME=$codename" >&2
  if [ "${LAIRU_PREFLIGHT_STRICT_TRIXIE:-0}" = "1" ]; then
    exit 1
  fi
fi

missing=0
find_command() {
  local command_name="$1"
  shift
  if command -v "$command_name" >/dev/null 2>&1; then
    command -v "$command_name"
    return 0
  fi
  for candidate in "$@"; do
    if [ -x "$candidate" ]; then
      printf '%s\n' "$candidate"
      return 0
    fi
  done
  return 1
}

CC_BIN="$(find_command cc || true)"
CARGO_BIN="$(find_command cargo || true)"
RUSTC_BIN="$(find_command rustc || true)"
PKG_CONFIG_BIN="$(find_command pkg-config || find_command pkgconf || true)"
LDCONFIG_BIN="$(find_command ldconfig /usr/sbin/ldconfig /sbin/ldconfig || true)"
LDD_BIN="$(find_command ldd /usr/bin/ldd || true)"

for command_pair in \
  "cc:$CC_BIN" \
  "cargo:$CARGO_BIN" \
  "rustc:$RUSTC_BIN" \
  "pkg-config:$PKG_CONFIG_BIN" \
  "ldconfig:$LDCONFIG_BIN" \
  "ldd:$LDD_BIN"; do
  command_name="${command_pair%%:*}"
  command_path="${command_pair#*:}"
  if [ -n "$command_path" ]; then
    printf '%-12s %s\n' "$command_name:" "$command_path"
  else
    echo "missing command: $command_name" >&2
    missing=1
  fi
done
if ! command -v rg >/dev/null 2>&1; then
  echo "optional developer command missing: rg (install ripgrep)" >&2
fi
if ! command -v rustfmt >/dev/null 2>&1; then
  echo "optional developer command missing: rustfmt (install rustfmt)" >&2
fi
if [ "$missing" -ne 0 ]; then
  echo "install on Trixie with:" >&2
  echo "  sudo apt remove rustup" >&2
  echo "  sudo apt install build-essential cargo rustc rustfmt pkg-config pkgconf ca-certificates libicu-dev libxml2 libxml2-dev libxslt1.1 libxslt1-dev ripgrep" >&2
fi
[ "$missing" -eq 0 ] || exit 1

if rustc_version="$("$RUSTC_BIN" --version 2>&1)"; then
  echo "rustc: $rustc_version"
else
  echo "rustc is present but not usable:" >&2
  printf '%s\n' "$rustc_version" >&2
  missing=1
fi
if cargo_version="$("$CARGO_BIN" --version 2>&1)"; then
  echo "cargo: $cargo_version"
else
  echo "cargo is present but not usable:" >&2
  printf '%s\n' "$cargo_version" >&2
  missing=1
fi
if [ "$missing" -ne 0 ]; then
  echo "Trixie currently has Debian rustup shims without a configured toolchain." >&2
  echo "For the Debian-packaged build path, replace rustup with rustc/cargo:" >&2
  echo "  sudo apt remove rustup" >&2
  echo "  sudo apt install cargo rustc" >&2
  echo "Alternatively configure rustup outside this preflight with a Rust 1.85+ toolchain." >&2
fi
[ "$missing" -eq 0 ] || exit 1

for package in icu-i18n icu-uc; do
  if "$PKG_CONFIG_BIN" --exists "$package"; then
    echo "$package: $("$PKG_CONFIG_BIN" --modversion "$package")"
  else
    echo "missing pkg-config package: $package" >&2
    missing=1
  fi
done
[ "$missing" -eq 0 ] || exit 1

ld_cache="$("$LDCONFIG_BIN" -p)"
for library in libicui18n.so libicuuc.so libicudata.so libxml2.so.2 libxslt.so.1 libexslt.so.0; do
  if grep -Fq "$library" <<<"$ld_cache"; then
    echo "library: $library"
  else
    echo "missing runtime library: $library" >&2
    missing=1
  fi
done
[ "$missing" -eq 0 ] || exit 1

stale_artifacts=0
for artifact in target/debug/lairu target/debug/lairu-fpm; do
  if [ -x "$artifact" ]; then
    ldd_output="$("$LDD_BIN" "$artifact" 2>&1 || true)"
    if grep -Eq 'not found|libicu(i18n|uc|data)\.so\.72' <<<"$ldd_output"; then
      echo "stale or unresolved dynamic links in $artifact; cargo clean is required" >&2
      stale_artifacts=1
    fi
  fi
done

if [ "$want_clean" = "1" ] || [ "$stale_artifacts" -eq 1 ]; then
  "$CARGO_BIN" clean
fi

if [ "$want_build" -eq 1 ]; then
  "$CARGO_BIN" build --locked --bin lairu --bin lairu-fpm
else
  "$CARGO_BIN" check --locked
fi

echo "Trixie preflight completed."
