#!/usr/bin/env bash
# Phase T5: combine seed manifest into seed.sql.
#
# seed.manifest -> seed.sql  (auto-applied by `supabase db reset`)
#
# seed.sql is gitignored; do not edit it directly.
set -euo pipefail

SUPABASE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

write_header() {
  cat <<'EOF'
-- ==============================================================================
-- LenserFight Platform — combined seeds
-- AUTO-GENERATED by supabase/combine-seeds.sh — edit seed.manifest and
-- seeds/**/*.sql; do not edit this file directly.
--
-- Schema-required lookup tables and system flags load first; demo / sample
-- data follows. Skip the demo sections in CI if you need a faster cold-boot.
-- ==============================================================================

SET statement_timeout = 0;
SET lock_timeout = 0;
SET idle_in_transaction_session_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SELECT pg_catalog.set_config('search_path', 'public, extensions', false);
SET check_function_bodies = false;
SET xmloption = content;
SET client_min_messages = warning;
SET row_security = off;
SELECT pg_catalog.set_config('identity_gov.allow_reserved_seed', 'on', false);

EOF
}

append_manifest_sql() {
  local manifest="$1"
  local out="$2"
  while IFS= read -r line || [[ -n "${line}" ]]; do
    line="${line#"${line%%[![:space:]]*}"}"
    line="${line%"${line##*[![:space:]]}"}"
    [[ -z "$line" ]] && continue
    [[ "$line" == \#* ]] && continue
    line="${line%%#*}"
    line="${line#"${line%%[![:space:]]*}"}"
    line="${line%"${line##*[![:space:]]}"}"
    [[ -z "$line" ]] && continue

    target="${SUPABASE_DIR}/${line}"
    if [[ ! -f "$target" ]]; then
      echo "ERROR: Manifest entry not found: ${line} (in $(basename "$manifest"))"
      exit 1
    fi
    {
      echo ""
      echo "-- >>> ${line}"
      cat "$target"
      echo ""
    } >>"$out"
  done < "$manifest"
}

# Accept optional --manifest <file> and --out <file> flags.
# Defaults:  seed.manifest → seed.sql
# Production: --manifest seed-production.manifest → seed-production.sql
MANIFEST="${SUPABASE_DIR}/seed.manifest"
OUT="${SUPABASE_DIR}/seed.sql"

while [[ $# -gt 0 ]]; do
  case "$1" in
    --manifest) MANIFEST="${SUPABASE_DIR}/$2"; shift 2 ;;
    --out)      OUT="${SUPABASE_DIR}/$2";      shift 2 ;;
    *) echo "Unknown option: $1"; exit 1 ;;
  esac
done

if [[ ! -f "$MANIFEST" ]]; then
  echo "ERROR: missing manifest: ${MANIFEST}"
  exit 1
fi

write_header >"$OUT"
append_manifest_sql "$MANIFEST" "$OUT"
echo "Wrote ${OUT} ($(wc -l <"$OUT") lines)"

# Coverage check: every .sql under seeds/ must appear in the default manifest.
# Skipped when using a non-default manifest (production manifests intentionally
# exclude demo/dev seeds).
DEFAULT_MANIFEST="${SUPABASE_DIR}/seed.manifest"
if [[ "${MANIFEST}" == "${DEFAULT_MANIFEST}" ]]; then
  missing=0
  shopt -s nullglob

  PROD_MANIFEST="${SUPABASE_DIR}/seed-production.manifest"

  check_listed() {
    local rel="$1"
    grep -qE "^[[:space:]]*${rel}[[:space:]]*(#|\$)" "${DEFAULT_MANIFEST}" 2>/dev/null \
      || grep -qE "(^|[[:space:]])${rel}([[:space:]]|$)" "${PROD_MANIFEST}" 2>/dev/null
  }

  for f in "${SUPABASE_DIR}"/seeds/*.sql; do
    base="seeds/$(basename "$f")"
    if ! check_listed "$base"; then
      echo "ERROR: ${base} exists on disk but is not listed in seed.manifest"
      missing=1
    fi
  done

  for f in "${SUPABASE_DIR}"/seeds/performance-data/*.sql; do
    base="seeds/performance-data/$(basename "$f")"
    if ! check_listed "$base"; then
      echo "WARN: ${base} exists on disk but is not listed in seed.manifest (performance-data is opt-in)"
    fi
  done

  shopt -u nullglob

  if [[ "$missing" -ne 0 ]]; then
    exit 1
  fi
fi
