#!/usr/bin/env bash
set -euo pipefail

# Config via env
GITEA_URL="${GITEA_URL:-https://git.biohazardvfx.com}"
OWNER="${OWNER:-Nicholai}"
REPO="${REPO:-bandit-runner}"
: "${TOKEN:?Set TOKEN env var with a Gitea API token}"

# curl wrapper: returns body on stdout, sets HTTP_CODE global
api() { # $1=METHOD $2=/path $3=[json-body]
  local m="$1" p="$2" body="${3:-}" tmp http
  tmp="$(mktemp)"
  if [[ -n "$body" ]]; then
    http="$(curl -fsS -o "$tmp" -w '%{http_code}' -X "$m" \
      "${GITEA_URL%/}/api/v1${p}" \
      -H "Authorization: token $TOKEN" \
      -H "Content-Type: application/json" \
      -d "$body")" || { rm -f "$tmp"; echo "curl failed $m $p" >&2; exit 1; }
  else
    http="$(curl -fsS -o "$tmp" -w '%{http_code}' -X "$m" \
      "${GITEA_URL%/}/api/v1${p}" \
      -H "Authorization: token $TOKEN" \
      -H "Content-Type: application/json")" || { rm -f "$tmp"; echo "curl failed $m $p" >&2; exit 1; }
  fi
  HTTP_CODE="$http"
  cat "$tmp"
  rm -f "$tmp"
}

# Get existing labels once (map name->id)
declare -A LABEL_IDS
load_labels() {
  local body; body="$(api GET "/repos/$OWNER/$REPO/labels")"
  if [[ "$HTTP_CODE" != "200" ]]; then
    echo "List labels failed: HTTP $HTTP_CODE" >&2; echo "$body" >&2; exit 1
  fi
  # requires jq
  while IFS=$'\t' read -r id name; do
    LABEL_IDS["$name"]="$id"
  done < <(jq -r '.[] | "\(.id)\t\(.name)"' <<<"$body")
}

json() { # name color desc -> compact JSON
  jq -c -n --arg n "$1" --arg c "$2" --arg d "$3" '{name:$n, color:$c, description:$d}'
}

# Gitea accepts hex with or without leading '#'. We'll strip '#'.
hex() { echo "${1#\#}"; }

upsert() { # name color desc
  local n="$1" c="$(hex "$2")" d="$3" payload code body id
  id="${LABEL_IDS[$n]:-}"
  payload="$(json "$n" "$c" "$d")"
  if [[ -n "$id" ]]; then
    body="$(api PATCH "/repos/$OWNER/$REPO/labels/$id" "$payload")"
    code="$HTTP_CODE"
    if [[ "$code" != "200" ]]; then echo "Update $n failed: HTTP $code $body" >&2; exit 1; fi
    echo "updated: $n (#$c)"
  else
    body="$(api POST "/repos/$OWNER/$REPO/labels" "$payload")"
    code="$HTTP_CODE"
    if [[ "$code" == "201" ]]; then
      echo "created: $n (#$c)"
    elif [[ "$code" == "422" ]]; then
      # race/exists: reload ids, patch
      load_labels
      id="${LABEL_IDS[$n]:-}"
      [[ -z "$id" ]] && { echo "cannot find $n after 422"; exit 1; }
      body="$(api PATCH "/repos/$OWNER/$REPO/labels/$id" "$payload")"
      [[ "$HTTP_CODE" == "200" ]] || { echo "update after 422 failed: $body"; exit 1; }
      echo "updated: $n (#$c)"
    else
      echo "create $n failed: HTTP $code $body" >&2; exit 1
    fi
  fi
}

# ---- run ----
command -v jq >/dev/null || { echo "jq not found"; exit 1; }
load_labels

upsert "type:feat"      "#3b82f6" "new feature"
upsert "type:fix"       "#ef4444" "bug fix"
upsert "type:docs"      "#10b981" "documentation"
upsert "type:chore"     "#64748b" "internal chore"

upsert "area:ui"        "#a855f7" "frontend UI"
upsert "area:runner"    "#f59e0b" "run coordination"
upsert "area:infra"     "#0ea5e9" "infra and deploy"
upsert "area:tooling"   "#14b8a6" "dev tooling"

upsert "prio:high"      "#dc2626" "high priority"
upsert "prio:med"       "#d97706" "medium priority"
upsert "prio:low"       "#16a34a" "low priority"

upsert "status:blocked"     "#111827" "blocked"
upsert "status:ready"       "#22c55e" "ready to pick up"
upsert "status:in-progress" "#2563eb" "in progress"
echo "done."
