#!/bin/sh
# Entry point for the bug-report collector, so agents and people start it through one
# stable path on every platform:
#
#   tools/bugreport [options]
#
# This is the POSIX half - Linux, macOS and Git Bash on Windows. PowerShell resolves
# the same string to tools/bugreport.ps1 first.
#
# tools/bugreport.py is the one part of the stack that has to run when nothing else
# does, so this script assumes nothing the preflight sets up: no .wikitool-tools.json,
# no venv. It looks for a Python itself, the way the preflight does - on Windows
# python, py -3, python3; elsewhere python3, python; every match on PATH in PATH
# order - and only then tries the venv's. It never starts anything under WindowsApps:
# there, python.exe and python3.exe are the Microsoft Store's aliases, and in Git Bash
# `python3` is exactly that. Every candidate is probed first, so one that is too old or
# that the machine refuses to run (a venv python.exe blocked by Defender) is passed over
# rather than ending the report.
#
# Without any Python 3.8 or newer it says so and exits 1, never 42: the collector opens
# no gate.
#
# CHEMENU_PREFLIGHT_PLATFORM stands in for the platform, as it does for the preflight;
# the test suite is its only user.
set -u
DIR=$(CDPATH='' cd -- "$(dirname -- "$0")" && pwd -P) || exit 1
MIN=3.8
# Exit 3 marks "a Python, but too old" apart from "did not start at all".
PROBE='import sys; sys.exit(0 if sys.version_info >= (3, 8) else 3)'

platform=${CHEMENU_PREFLIGHT_PLATFORM:-}
if [ -z "$platform" ]; then
    case "$(uname -s 2>/dev/null)" in
        MINGW*|MSYS*|CYGWIN*) platform=windows ;;
        *) platform=other ;;
    esac
fi

if [ "$platform" = windows ]; then
    order="python: py:-3 python3:"
    looked="python, py -3, python3"
else
    order="python3: python:"
    looked="python3, python"
fi

is_store_alias() {
    case "$1" in *[Ww]indows[Aa]pps/*|*[Ww]indows[Aa]pps\\*) return 0 ;; esac
    return 1
}

# Every executable called <name> on PATH, in PATH order, store aliases dropped.
on_path() {
    set -f
    old_ifs=$IFS
    IFS=:
    for d in $PATH; do
        [ -n "$d" ] || d=.
        for f in "$d/$1" "$d/$1.exe"; do
            if [ -f "$f" ] && [ -x "$f" ] && ! is_store_alias "$f"; then
                printf '%s\n' "$f"
            fi
        done
    done
    IFS=$old_ifs
    set +f
}

PY="" EXTRA="" TOO_OLD=""

probe() { # <path> [extra argument, e.g. -3 for py] -> sets PY/EXTRA on success
    "$@" -c "$PROBE" >/dev/null 2>&1
    status=$?
    if [ "$status" -eq 0 ]; then
        PY=$1 EXTRA=${2:-}
        return 0
    fi
    if [ "$status" -eq 3 ]; then
        TOO_OLD="$TOO_OLD
  $1"
    fi
    return 1
}

for candidate in $order; do
    name=${candidate%%:*}
    extra=${candidate#*:}
    found=$(on_path "$name")
    [ -n "$found" ] || continue
    # A here-document, not a pipe: `break 2` has to leave the outer loop of this
    # shell, and a path may contain spaces ("Program Files").
    while IFS= read -r path; do
        if [ -n "$extra" ]; then
            probe "$path" "$extra" && break 2
        else
            probe "$path" && break 2
        fi
    done <<EOF
$found
EOF
done

if [ -z "$PY" ]; then
    for venv in "$DIR/.venv/bin/python" "$DIR/.venv/Scripts/python.exe"; do
        [ -f "$venv" ] && probe "$venv" && break
    done
fi

if [ -n "$PY" ]; then
    if [ -n "$EXTRA" ]; then
        exec "$PY" "$EXTRA" "$DIR/bugreport.py" "$@"
    fi
    exec "$PY" "$DIR/bugreport.py" "$@"
fi

{
    echo "No Python $MIN or newer could be started, so the bug-report collector did not run."
    echo "Looked for $looked on PATH, then the one in tools/.venv. Microsoft Store aliases"
    echo "under WindowsApps are skipped on purpose - they do not run Python."
    if [ -n "$TOO_OLD" ]; then
        echo "Found, but older than $MIN:$TOO_OLD"
    fi
    echo
    echo "Install Python $MIN or newer, or start the collector directly with the full path"
    echo "of one that works:"
    echo
    echo "  <full path to python> tools/bugreport.py <the same options>"
} >&2
exit 1
