#!/usr/bin/env bash
# Run locally before deploy/publish-release.sh, on the branch you're
# about to release. Builds everything the server can never build for
# itself (composer/npm - see deploy/README.md for why) and commits the
# result onto the current branch.
set -euo pipefail

cd "$(dirname "$0")/.."

# composer.json requires PHP >= 8.4.1, but plain `php`/`composer` on this
# machine resolve to whatever's first in PATH (8.2 here) - composer's own
# shebang is `#!/usr/bin/env php`, so running it unqualified silently
# picks up the wrong version and fails with a platform_check.php fatal.
# Pin an explicit 8.4+ binary instead of trusting PATH.
PHP_BIN=""
for candidate in php8.4 php8.5 php; do
    if command -v "$candidate" >/dev/null 2>&1; then
        version="$("$candidate" -r 'echo PHP_VERSION;')"
        if [ "$(printf '%s\n8.4.0\n' "$version" | sort -V | head -n1)" = "8.4.0" ]; then
            PHP_BIN="$(command -v "$candidate")"
            break
        fi
    fi
done

if [ -z "$PHP_BIN" ]; then
    echo "No PHP >= 8.4 binary found (checked php8.4, php8.5, php) - install one or adjust this script's candidate list." >&2
    exit 1
fi

echo "==> Using $PHP_BIN ($("$PHP_BIN" -r 'echo PHP_VERSION;'))"

COMPOSER_BIN="$(command -v composer)"

# Guarantee dev dependencies (incl. phpunit) are actually present
# before testing. This matters even with the test-before-strip
# ordering below: if a *previous* run of this same script already
# stripped dev deps and nobody restored them since (a real thing that
# happened), `php artisan test` doesn't fail when phpunit's command
# is missing - it falls back to listing the "test" namespace and exits
# 0. `set -e` never catches that "success", so the script would
# silently skip testing entirely and go straight to building/
# committing a release that was never actually run through the suite.
if [ ! -x vendor/bin/phpunit ]; then
    echo "==> vendor/ is missing dev dependencies (phpunit) - restoring them first..."
    "$PHP_BIN" "$COMPOSER_BIN" install
fi

# Run the test suite BEFORE stripping dev dependencies - phpunit itself
# is a dev dependency, so if `composer install --no-dev` ran first,
# `artisan test` would have nothing left to run it with and this step
# would silently stop testing anything at all.
echo "==> Running the test suite (before dev dependencies are removed)..."
"$PHP_BIN" artisan test

echo "==> Installing production Composer dependencies (no dev)..."
"$PHP_BIN" "$COMPOSER_BIN" install --no-dev --optimize-autoloader

# Same PATH-drift problem as PHP above: node/npm here come from nvm and
# the active version varies by shell/session, but Vite needs a specific
# floor (^20.19.0 || >=22.12.0, per node_modules/vite/package.json).
# Prefer the newest matching version already installed under nvm, fall
# back to plain `node` in PATH, and always pair npm from that same
# install (mixing a system npm with an nvm node has caused mismatches
# before).
NODE_BIN=""

if [ -d "$HOME/.nvm/versions/node" ]; then
    for candidate in $(ls -1 "$HOME/.nvm/versions/node" 2>/dev/null | sort -V -r); do
        candidate_path="$HOME/.nvm/versions/node/$candidate/bin/node"

        if [ -x "$candidate_path" ]; then
            version="$("$candidate_path" --version | sed 's/^v//')"

            if [ "$(printf '%s\n20.19.0\n' "$version" | sort -V | head -n1)" = "20.19.0" ]; then
                NODE_BIN="$candidate_path"
                break
            fi
        fi
    done
fi

if [ -z "$NODE_BIN" ] && command -v node >/dev/null 2>&1; then
    version="$(node --version | sed 's/^v//')"

    if [ "$(printf '%s\n20.19.0\n' "$version" | sort -V | head -n1)" = "20.19.0" ]; then
        NODE_BIN="$(command -v node)"
    fi
fi

if [ -z "$NODE_BIN" ]; then
    echo "No Node >= 20.19 found (checked nvm installs under ~/.nvm/versions/node, and plain 'node' in PATH)." >&2
    exit 1
fi

NPM_BIN="$(dirname "$NODE_BIN")/npm"
echo "==> Using $NODE_BIN ($("$NODE_BIN" --version))"

echo "==> Installing and building frontend assets..."
"$NPM_BIN" install
"$NPM_BIN" run build

echo "==> Staging built artifacts (vendor/, public/build/)..."
git add -A vendor public/build

if git diff --cached --quiet; then
    echo "==> Nothing changed in vendor/ or public/build/ - nothing to commit."
else
    git commit -m "Build release artifacts"
fi

cat <<'EOF'

Done. vendor/ and public/build/ are committed on this branch.

IMPORTANT: `composer install --no-dev` just removed dev dependencies
(phpunit, etc.) from this local vendor/ folder. Run a plain
`composer install` again before you keep developing locally - this
script is meant to be the last thing you run in a work session, right
before deploy/publish-release.sh, not something you run mid-session.
EOF
