#!/bin/bash
# Vendoring script for hermes-chatto-plugin
#
# Downloads chattolib and all its dependencies with uv and vendors them into
# vendor/. Three of them (pyqwest, protobuf, protobuf-py-ext) ship compiled
# extension modules, so the tree is split by platform:
#
#   vendor/common/                 pure-Python packages, shared
#   vendor/platform/<tag>/         compiled extensions, one dir per platform
#
# vendor_path.py picks the right directory at import time.
#
# Usage:
#   ./vendor_chattolib.sh                       # all default platforms
#   PLATFORMS="linux-x86_64" ./vendor_chattolib.sh
#   CHATTOLIB_SPEC="chattolib==0.4.20" ./vendor_chattolib.sh
#   VENDOR_DIR="/tmp/vendor-alt" ./vendor_chattolib.sh

set -euo pipefail

PLUGIN_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# Overridable from the environment; unset or empty falls back to the plugin's
# own vendor/ so neither `set -u` nor a stray empty value can break startup.
VENDOR_DIR="${VENDOR_DIR:-$PLUGIN_DIR/vendor}"
BUILD_DIR="$(mktemp -d)"
trap 'rm -rf "$BUILD_DIR"' EXIT

CHATTOLIB_SPEC="${CHATTOLIB_SPEC:-chattolib>=0.4.20}"

# Wheels are resolved for this Python version. 3.11 is the project's minimum
# (pyproject: requires-python) AND the version for which the binary packages
# still provide cp310-abi3 wheels — those are forward compatible, so one build
# covers 3.11, 3.12, 3.13 and 3.14. Do not raise this without checking that
# the resulting .so files are still abi3.
PYTHON_VERSION="${PYTHON_VERSION:-3.11}"

# Platform tag (as used in vendor/platform/ and by vendor_path.py) mapped to
# the uv --python-platform target. Add entries here to support more platforms;
# vendor_path.py derives the same tags from platform.system()/machine().
platform_target() {
    case "$1" in
        linux-x86_64)       echo "x86_64-unknown-linux-gnu" ;;
        linux-aarch64)      echo "aarch64-unknown-linux-gnu" ;;
        linux-x86_64-musl)  echo "x86_64-unknown-linux-musl" ;;
        linux-aarch64-musl) echo "aarch64-unknown-linux-musl" ;;
        macos-arm64)        echo "aarch64-apple-darwin" ;;
        macos-x86_64)       echo "x86_64-apple-darwin" ;;
        windows-amd64)      echo "x86_64-pc-windows-msvc" ;;
        *)                  return 1 ;;
    esac
}

# Default set: Linux (deployment, both architectures) and Apple Silicon (dev).
DEFAULT_PLATFORMS="linux-x86_64 linux-aarch64 macos-arm64"
read -r -a PLATFORM_LIST <<< "${PLATFORMS:-$DEFAULT_PLATFORMS}"

if ! command -v uv > /dev/null 2>&1; then
    echo "❌ uv nicht gefunden — siehe https://docs.astral.sh/uv/" >&2
    exit 1
fi

echo "📦 Vendoring '$CHATTOLIB_SPEC' für: ${PLATFORM_LIST[*]}"
echo "   (Python $PYTHON_VERSION, nur Binär-Wheels — kein Bauen aus Sourcen)"

for tag in "${PLATFORM_LIST[@]}"; do
    if ! target="$(platform_target "$tag")"; then
        echo "❌ Unbekannte Plattform '$tag'. Bekannt: linux-x86_64, linux-aarch64," >&2
        echo "   linux-x86_64-musl, linux-aarch64-musl, macos-arm64, macos-x86_64, windows-amd64" >&2
        exit 1
    fi
    echo "  → $tag ($target)"
    # --only-binary :all: is required: a source distribution could not be built
    # for a foreign platform, and building it for the host would silently
    # produce artifacts for the wrong architecture.
    uv pip install \
        --target "$BUILD_DIR/$tag" \
        --python-platform "$target" \
        --python-version "$PYTHON_VERSION" \
        --only-binary :all: \
        --quiet \
        "$CHATTOLIB_SPEC"
done

echo "🧹 Bereinige alten vendor-Ordner..."
# Guard before the destructive step: this script must never run rm -rf with
# an empty or unset target, whatever future edits do to the assignment above.
: "${VENDOR_DIR:?VENDOR_DIR ist nicht gesetzt — Abbruch vor rm -rf}"
rm -rf "$VENDOR_DIR"
mkdir -p "$VENDOR_DIR"

echo "✂️  Trenne plattformunabhängige von binären Paketen..."
python3 "$PLUGIN_DIR/vendor_split.py" "$BUILD_DIR" "$VENDOR_DIR" "${PLATFORM_LIST[@]}"

echo "📄 Erstelle __init__.py Marker..."
touch "$VENDOR_DIR/__init__.py"

find "$VENDOR_DIR" -type d -name "__pycache__" -exec rm -rf {} + 2> /dev/null || true

echo "🔍 Verifiziere Import für die aktuelle Plattform..."
if python3 -c "
import sys
sys.path.insert(0, '$PLUGIN_DIR')
from vendor_path import setup_vendor_path, platform_tag
try:
    setup_vendor_path()
except ImportError as exc:
    print(f'   ⓘ  {exc}')
    sys.exit(0)
import chattolib.client
print(f'   ✓ chattolib importiert ({platform_tag()})')
"; then
    :
else
    echo "❌ Import-Verifikation fehlgeschlagen" >&2
    exit 1
fi

echo "✓ Fertig: $(du -sh "$VENDOR_DIR" | cut -f1) in $VENDOR_DIR"
echo "  'git add vendor/' nicht vergessen."
