#!/usr/bin/env bash
#
# Baut alle Ink-Dialoge zu .ink.json, die das Spiel lesen kann.
#
# Für die Autorin: Schreib deine Dialoge als .ink-Dateien in
#   assets/interactions/
# und führ danach dieses Skript aus:
#   ./tools/build-dialogues.sh
# Fertig — das Spiel liest die erzeugten .ink.json.
#
# Standardmäßig wird nur neu gebaut, was sich seit dem letzten Mal
# geändert hat. Mit  -f / --force  wird alles neu gebaut.

set -euo pipefail

# Repo-Wurzel relativ zum Skript bestimmen — egal, von wo aufgerufen.
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
root="$(cd "$script_dir/.." && pwd)"
ink_dir="$root/assets/interactions"

force=0
case "${1:-}" in
    -f|--force) force=1 ;;
    "")         ;;
    *) echo "Unbekannte Option: $1 (nur -f/--force)" >&2; exit 2 ;;
esac

# inklecate finden: $INKLECATE → mitgeliefertes tools/inklecate → PATH.
find_inklecate() {
    if [ -n "${INKLECATE:-}" ] && [ -x "$INKLECATE" ]; then
        echo "$INKLECATE"; return 0
    fi
    if [ -x "$script_dir/inklecate" ]; then
        echo "$script_dir/inklecate"; return 0
    fi
    if command -v inklecate >/dev/null 2>&1; then
        command -v inklecate; return 0
    fi
    return 1
}

if ! inklecate="$(find_inklecate)"; then
    cat >&2 <<'EOF'
Fehler: inklecate nicht gefunden.
  Lege das Linux-Binary nach  tools/inklecate  (chmod +x),
  setze $INKLECATE auf den Pfad, oder installiere es in den PATH.
  Quelle: https://github.com/inkle/ink/releases
EOF
    exit 1
fi

if [ ! -d "$ink_dir" ]; then
    echo "Kein Dialog-Ordner: $ink_dir" >&2
    exit 1
fi

# Prüft eine .ink-Datei auf Zeichen außerhalb von CP437 und gibt sie aus.
# Exit-Code 1 wenn Treffer gefunden, sonst 0.
check_cp437() {
    python3 - "$1" <<'PYEOF'
import sys
path = sys.argv[1]
cp437 = set(bytes(range(256)).decode('cp437', errors='replace'))
hits = []
with open(path, encoding='utf-8') as f:
    for lineno, line in enumerate(f, 1):
        for ch in line:
            if ord(ch) > 127 and ch not in cp437:
                hits.append(f'    Z.{lineno}: U+{ord(ch):04X} {repr(ch)}')
for h in hits:
    print(h)
sys.exit(1 if hits else 0)
PYEOF
}

built=0 skipped=0 failed=0
shopt -s nullglob
for src in "$ink_dir"/*.ink; do
    out="${src%.ink}.ink.json"
    name="$(basename "$src")"

    # CP437-Warnung: läuft immer, unabhängig vom Build-Status.
    if ! cp437_warn="$(check_cp437 "$src")"; then
        printf '  WARNUNG   %s -- Nicht-CP437-Zeichen:\n' "$name"
        printf '%s\n' "$cp437_warn"
    fi

    # Inkrementell: überspringen, wenn Ausgabe existiert und neuer ist.
    if [ "$force" -eq 0 ] && [ -f "$out" ] && [ "$out" -nt "$src" ]; then
        printf '  aktuell   %s\n' "$name"
        skipped=$((skipped + 1))
        continue
    fi

    # inklecate-Ausgabe einsammeln; nur bei Problemen/Warnungen zeigen.
    if log="$("$inklecate" -o "$out" "$src" 2>&1)"; then
        printf '  gebaut    %s\n' "$name"
        built=$((built + 1))
        [ -n "$log" ] && printf '%s\n' "$log" | sed 's/^/              /'
    else
        printf '  FEHLER    %s\n' "$name"
        printf '%s\n' "$log" | sed 's/^/              /'
        failed=$((failed + 1))
    fi
done

echo "—— $built gebaut, $skipped aktuell, $failed fehlgeschlagen ——"
[ "$failed" -eq 0 ]
