#!/usr/bin/env bash
# Sanity-check every installed tool. Exits non-zero if anything is missing.

set -euo pipefail
source "$(dirname "$0")/common.sh"

fails=0

check() {
    local label="$1"; shift
    if "$@" >/dev/null 2>&1; then
        printf '  [ OK ]  %s\n' "$label"
    else
        printf '  [FAIL]  %s  (%s)\n' "$label" "$*"
        fails=$((fails + 1))
    fi
}

log "verifying toolchain"

# Build tools
check "cmake"          cmake --version
check "ninja"          ninja --version
check "clang (host)"   clang --version
check "git"            git --version

# llvm-mos source + SDK
check "llvm-mos source tree"   test -d "$TOOLS_DIR/llvm-mos/.git"
check "llvm-mos-sdk extracted" test -x "$TOOLS_DIR/llvm-mos-sdk/bin/mos-common-clang"

# W65816 backend integration
check "W65816 source symlinked into llvm-mos" \
    test -L "$TOOLS_DIR/llvm-mos/llvm/lib/Target/W65816/W65816ISelLowering.cpp"
check "W65816 clang built"          test -x "$TOOLS_DIR/llvm-mos-build/bin/clang"
check "W65816 llc built"            test -x "$TOOLS_DIR/llvm-mos-build/bin/llc"
check "W65816 llvm-mc built"        test -x "$TOOLS_DIR/llvm-mos-build/bin/llvm-mc"
check "llc lists w65816 target" \
    bash -c "'$TOOLS_DIR/llvm-mos-build/bin/llc' --version 2>/dev/null | grep -q '^[[:space:]]*w65816[[:space:]]'"

# link816 + omfEmit
check "link816 binary"    test -x "$TOOLS_DIR/link816"
check "omfEmit binary"    test -x "$TOOLS_DIR/omfEmit"

# Runtime libraries (built objects we link into every program)
check "runtime/crt0.o"       test -s "$PROJECT_ROOT/runtime/crt0.o"
check "runtime/libc.o"       test -s "$PROJECT_ROOT/runtime/libc.o"
check "runtime/libgcc.o"     test -s "$PROJECT_ROOT/runtime/libgcc.o"
check "runtime/softFloat.o"  test -s "$PROJECT_ROOT/runtime/softFloat.o"
check "runtime/softDouble.o" test -s "$PROJECT_ROOT/runtime/softDouble.o"

# MAME + ROMs
check "mame binary"                 command -v mame
check "mame Lua console support"    bash -c "mame -showusage 2>&1 | grep -q -- '-console'"
check "rom: apple2gs.zip"           test -s "$TOOLS_DIR/mame/roms/apple2gs.zip"
check "rom: apple2gsr1.zip"         test -s "$TOOLS_DIR/mame/roms/apple2gsr1.zip"

# Calypsi benchmark (optional; --skip-calypsi at install skips this).
if [ -d "$TOOLS_DIR/calypsi" ]; then
    check "calypsi cc65816" \
        test -x "$TOOLS_DIR/calypsi/usr/local/lib/calypsi-65816-5.16/bin/cc65816"
fi

# Toolbox bindings come from NList.Data (Dave Lyons' NiftyList catalog
# at tools/nlist/NList.Data.txt) — no ORCA/OPUS source required.
check "nlist data"      test -s "$PROJECT_ROOT/tools/nlist/NList.Data.txt"

# End-to-end smoke: compile a tiny C program for W65816 to prove the
# toolchain actually produces machine code.
echo
log "end-to-end compile check"
tmp=$(mktemp -d -t llvm816-verify.XXXXXX)
trap "rm -rf '$tmp'" EXIT
cat > "$tmp/hello.c" <<'EOF'
int answer(void) { return 42; }
EOF
if "$TOOLS_DIR/llvm-mos-build/bin/clang" --target=w65816 -O2 -c "$tmp/hello.c" \
       -o "$tmp/hello.o" 2>/dev/null \
   && "$TOOLS_DIR/llvm-mos-build/bin/llvm-objdump" --triple=w65816 -d "$tmp/hello.o" 2>/dev/null \
        | grep -q "lda"; then
    printf '  [ OK ]  C -> w65816 .o compile produces lda instruction\n'
else
    printf '  [FAIL]  end-to-end compile failed\n'
    fails=$((fails + 1))
fi

echo
if [ "$fails" -eq 0 ]; then
    log "all checks passed"
    exit 0
else
    die "$fails check(s) failed"
fi
