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

API_BASE="${API_BASE:-http://127.0.0.1:5084}"
ADMIN_SESSION_TOKEN="${ADMIN_SESSION_TOKEN:-}"

fail() {
  printf 'smoke failed: %s\n' "$*" >&2
  exit 1
}

require_command() {
  command -v "$1" >/dev/null 2>&1 || fail "missing required command: $1"
}

http_json() {
  local url="$1"
  shift || true
  curl -fsS "$@" "$url"
}

json_value() {
  local expression="$1"
  node -e "
let data = '';
process.stdin.on('data', chunk => data += chunk);
process.stdin.on('end', () => {
  const root = JSON.parse(data);
  const value = (${expression})(root);
  if (typeof value === 'object') {
    console.log(JSON.stringify(value));
  } else {
    console.log(value ?? '');
  }
});
"
}

require_command curl
require_command node

printf '== VTuber Awards local smoke ==\n'
printf 'API: %s\n' "$API_BASE"

printf '\n[1/6] health\n'
http_json "$API_BASE/api/health" >/tmp/vtsa-smoke-health.json
cat /tmp/vtsa-smoke-health.json
printf '\n'

printf '\n[2/6] database health\n'
http_json "$API_BASE/api/health/database" >/tmp/vtsa-smoke-db.json
cat /tmp/vtsa-smoke-db.json
printf '\n'
can_connect="$(json_value 'root => root.canConnect' </tmp/vtsa-smoke-db.json)"
if [[ "$can_connect" != "true" ]]; then
  fail "database cannot connect"
fi

printf '\n[3/6] public overview\n'
http_json "$API_BASE/api/public/overview" >/tmp/vtsa-smoke-overview.json
year="$(json_value 'root => root.year' </tmp/vtsa-smoke-overview.json)"
season_id="$(json_value 'root => root.seasonId' </tmp/vtsa-smoke-overview.json)"
printf 'current season: year=%s seasonId=%s\n' "$year" "$season_id"
if [[ -z "$year" || -z "$season_id" ]]; then
  fail "public overview did not expose current season"
fi

printf '\n[4/6] public category structure\n'
http_json "$API_BASE/api/public/seasons/$year/categories" >/tmp/vtsa-smoke-categories.json
category_count="$(json_value 'root => root.categories?.length ?? 0' </tmp/vtsa-smoke-categories.json)"
legacy_count="$(json_value 'root => (root.categories ?? []).filter(c => ["Main Awards", "Discovery", "Gaming", "Creative", "Performance", "Entertainment", "Community", "Collab"].includes(c.groupName)).length' </tmp/vtsa-smoke-categories.json)"
main_group_count="$(json_value 'root => new Set((root.categories ?? []).map(c => c.groupName)).size' </tmp/vtsa-smoke-categories.json)"
printf 'categories=%s mainGroups=%s legacyParents=%s\n' "$category_count" "$main_group_count" "$legacy_count"
if [[ "$category_count" == "0" ]]; then
  fail "public categories are empty"
fi
if [[ "$legacy_count" != "0" ]]; then
  fail "legacy parent labels are still exposed publicly"
fi

printf '\n[5/6] admin endpoints (optional)\n'
if [[ -z "$ADMIN_SESSION_TOKEN" ]]; then
  printf 'skipped: set ADMIN_SESSION_TOKEN to check admin season/team endpoints\n'
else
  auth_header=( -H "Authorization: Bearer $ADMIN_SESSION_TOKEN" )
  http_json "$API_BASE/api/admin/seasons" "${auth_header[@]}" >/tmp/vtsa-smoke-admin-seasons.json
  admin_season_count="$(json_value 'root => Array.isArray(root) ? root.length : (root.seasons?.length ?? 0)' </tmp/vtsa-smoke-admin-seasons.json)"
  printf 'admin seasons=%s\n' "$admin_season_count"
  if [[ "$admin_season_count" == "0" ]]; then
    fail "admin seasons endpoint returned no seasons"
  fi

  http_json "$API_BASE/api/admin/seasons/$season_id" "${auth_header[@]}" >/tmp/vtsa-smoke-admin-detail.json
  voting_groups="$(json_value 'root => root.votingWorkspace?.categories?.length ?? 0' </tmp/vtsa-smoke-admin-detail.json)"
  subcategory_templates="$(json_value 'root => root.subcategoryTemplates?.length ?? 0' </tmp/vtsa-smoke-admin-detail.json)"
  printf 'admin detail: votingCategories=%s subcategoryTemplates=%s\n' "$voting_groups" "$subcategory_templates"
  if [[ "$voting_groups" == "0" || "$subcategory_templates" == "0" ]]; then
    fail "admin detail is missing voting workspace or subcategory templates"
  fi

  http_json "$API_BASE/api/admin/team" "${auth_header[@]}" >/tmp/vtsa-smoke-admin-team.json
  permissions="$(json_value 'root => (root.permissions ?? []).map(p => p.key).sort().join(",")' </tmp/vtsa-smoke-admin-team.json)"
  printf 'permission keys=%s\n' "$permissions"
  node -e '
const fs = require("fs");
const root = JSON.parse(fs.readFileSync("/tmp/vtsa-smoke-admin-team.json", "utf8"));
const keys = new Set((root.permissions ?? []).map(item => item.key));
const required = ["dashboard","years","nominations","categories","candidates","clips","content","risk","audit","analytics","voting","winners","settings","team"];
const missing = required.filter(key => !keys.has(key));
if (missing.length) {
  console.error(`missing permission keys: ${missing.join(", ")}`);
  process.exit(1);
}
'
fi

printf '\n[6/6] smoke complete\n'
