#!/usr/bin/env bash
# gstack-slug — output project slug and sanitized branch name
# Usage: eval "$(gstack-slug)"  → sets SLUG and BRANCH variables
# Or:    gstack-slug            → prints SLUG=... and BRANCH=... lines
#
# Security: output is sanitized to [a-zA-Z0-9._-] only, preventing
# shell injection when consumed via source or eval.
set -euo pipefail

CACHE_DIR="$HOME/.gstack/slug-cache"
PROJECT_DIR="$(pwd)"
# Encode absolute path as cache key: /Users/j/foo → _Users_j_foo
CACHE_KEY=$(printf '%s' "$PROJECT_DIR" | tr '/' '_')
CACHE_FILE="${CACHE_DIR}/${CACHE_KEY}"

# 1. Try cached slug first (guarantees consistency across sessions)
if [[ -f "$CACHE_FILE" ]]; then
  SLUG=$(cat "$CACHE_FILE")
fi

# 2. If no cache, compute from git remote (separated from pipeline to avoid
#    pipefail swallowing the error and producing an empty slug)
if [[ -z "${SLUG:-}" ]]; then
  REMOTE_URL=$(git remote get-url origin 2>/dev/null) || REMOTE_URL=""
  if [[ -n "$REMOTE_URL" ]]; then
    RAW_SLUG=$(printf '%s' "$REMOTE_URL" | sed 's|.*[:/]\([^/]*/[^/]*\)\.git$|\1|;s|.*[:/]\([^/]*/[^/]*\)$|\1|' | tr '/' '-')
    SLUG=$(printf '%s' "$RAW_SLUG" | tr -cd 'a-zA-Z0-9._-')
  fi
fi

# 3. Fallback to basename only when there's truly no git remote configured
SLUG="${SLUG:-$(basename "$PWD" | tr -cd 'a-zA-Z0-9._-')}"

# 3b. Re-sanitize unconditionally before the value is echoed into `eval`/`source`
#     output. The compute (2) and fallback (3) paths already filter, but a value
#     read straight from the cache file (1) does NOT — a poisoned
#     ~/.gstack/slug-cache/<key> would otherwise inject shell into
#     `eval "$(gstack-slug)"`. Filtering here honors the [a-zA-Z0-9._-] invariant
#     promised in the header on every path, and heals a poisoned cache on write (4).
SLUG=$(printf '%s' "$SLUG" | tr -cd 'a-zA-Z0-9._-')

# 4. Cache the slug for future sessions (atomic write, fail silently)
if [[ -n "$SLUG" ]]; then
  mkdir -p "$CACHE_DIR" 2>/dev/null || true
  CACHE_TMP=$(mktemp "$CACHE_DIR/.slug-XXXXXX" 2>/dev/null) || CACHE_TMP=""
  if [[ -n "$CACHE_TMP" ]]; then
    printf '%s' "$SLUG" > "$CACHE_TMP" && mv "$CACHE_TMP" "$CACHE_FILE" 2>/dev/null || rm -f "$CACHE_TMP" 2>/dev/null
  fi
fi

RAW_BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) || RAW_BRANCH=""
BRANCH=$(printf '%s' "${RAW_BRANCH:-}" | tr -cd 'a-zA-Z0-9._-')
BRANCH="${BRANCH:-unknown}"
echo "SLUG=$SLUG"
echo "BRANCH=$BRANCH"
