#!/usr/bin/env bash
# One command that answers "is this shippable" - Python tests + frontend lint.
#
# ponytail: this IS the CI. The remote is self-hosted Gitea with no act_runner,
# so a .github/workflows file would never execute. Run this before tagging a
# release; wire it to a runner the day one exists.
set -uo pipefail
cd "$(dirname "$0")/.."

fail=0

if [ ! -x Promethean/bin/python ]; then
    echo "!! no Promethean venv - run ./install.sh first" >&2
    exit 1
fi

echo "== pytest =="
# Explicit dirs: a bare `pytest` would walk Promethean/ and node_modules too.
Promethean/bin/python -m pytest -q tests management || fail=1

echo "== eslint =="
if [ -d interface/web/node_modules ]; then
    (cd interface/web && npm run lint) || fail=1
else
    echo "-- skipped: interface/web/node_modules missing (npm install)"
fi

echo "== frontend unit tests =="
# The JSX/TSX transform behind the preview window is a pure module with a
# node --test suite. Nothing else in the frontend has tests, so this is cheap;
# without it the transform's silent-wrong cases go unguarded.
if [ -d interface/web/node_modules ]; then
    (cd interface/web && npm test) || fail=1
else
    echo "-- skipped: interface/web/node_modules missing (npm install)"
fi

echo "== powershell parse =="
# The Windows installer has died at parse twice. Cheap to catch here if pwsh
# happens to be installed on the Linux box; the ASCII guard in tests/ is the
# portable half of the same check.
if command -v pwsh >/dev/null; then
    for f in install-windows.ps1 launch_nexus.ps1; do
        pwsh -NoProfile -Command "\$e=\$null
            [System.Management.Automation.Language.Parser]::ParseFile('$f',[ref]\$null,[ref]\$e) | Out-Null
            if (\$e) { \$e | ForEach-Object { Write-Host '$f:' \$_.Message }; exit 1 }" || fail=1
    done
else
    echo "-- skipped: pwsh not installed"
fi

echo "== shell parse =="
for f in scripts/install-termux.sh install-macos.sh launch_nexus.sh management/nexus-cli.sh; do
    [ -f "$f" ] && { bash -n "$f" || fail=1; }
done

echo "== packaging =="
# The wheel is the other shippable artifact, so it belongs in the same gate:
# a broken pyproject or a missing web build only shows up at build time.
if Promethean/bin/python -c "import build, twine" 2>/dev/null; then
    rm -rf .build-check
    if Promethean/bin/python -m build --outdir .build-check >/dev/null 2>&1; then
        Promethean/bin/python -m twine check .build-check/* || fail=1
        # The compiled UI has to actually be inside the wheel - a wheel that
        # builds but ships no dist/ serves a blank page.
        Promethean/bin/python - <<'PY' || fail=1
import glob, sys, zipfile
wheels = glob.glob(".build-check/*.whl")
if not wheels:
    sys.exit("no wheel produced")
names = zipfile.ZipFile(wheels[0]).namelist()
if not any(n.startswith("synapse/_resources/web/") for n in names):
    sys.exit("wheel is missing the compiled web UI (cd interface/web && npm run build)")
if not any(n.startswith("synapse/_resources/playbooks/") for n in names):
    sys.exit("wheel is missing the seed playbooks")
if "synapse/curry_core.py" not in names or "synapse/curry_store.py" not in names:
    sys.exit("wheel is missing vendored Curry (synapse/curry_core.py / curry_store.py)")
if "synapse/slash_commands.py" not in names:
    sys.exit("wheel is missing synapse/slash_commands.py")
print(f"wheel OK: {len(names)} files")
PY
    else
        echo "!! wheel build failed"; fail=1
    fi
    rm -rf .build-check
else
    echo "-- skipped: build/twine missing (pip install -e '.[dev]')"
fi

[ "$fail" -eq 0 ] && echo "OK" || echo "FAILED"
exit "$fail"
