#!/usr/bin/env bash
# RON content validator — wrapper for the Rust validate_ron binary (#611).
#
# Usage:
#   tooling/validate-ron <file.ron> <zone|zone_type|culture>
#   tooling/validate-ron --check-name-collisions <content/dir/>
#
# Examples:
#   tooling/validate-ron server/content/global/zone-types/rural_agricultural.ron zone_type
#   tooling/validate-ron server/content/global/culture-van-maanens-star.example.ron culture
#   tooling/validate-ron server/content/global/zone-identity-spec.example.ron zone
#   tooling/validate-ron --check-name-collisions server/content/global/
#
# --check-name-collisions:
#   Scans all culture-*.ron files in the given directory. Extracts naming.given_names
#   and naming.family_names pools from each file. Reports any name that appears in more
#   than one culture's pool. Exits 1 on collision; exits 0 if no collisions found.
#   Output is machine-readable (one collision per line).

set -euo pipefail

# --- Name collision mode --------------------------------------------------
if [ "${1:-}" = "--check-name-collisions" ]; then
    if [ $# -lt 2 ]; then
        echo "Usage: tooling/validate-ron --check-name-collisions <directory>"
        exit 1
    fi
    SCAN_DIR="$2"
    if [ ! -d "$SCAN_DIR" ]; then
        echo "Error: directory not found: $SCAN_DIR"
        exit 1
    fi
    python3 - "$SCAN_DIR" <<'PYEOF'
import sys
import re
import os
import glob

scan_dir = sys.argv[1]
pattern = os.path.join(scan_dir, "culture-*.ron")
files = sorted(glob.glob(pattern))

if not files:
    print(f"No culture-*.ron files found in: {scan_dir}")
    sys.exit(0)

def extract_names_from_block(text, field):
    """Extract quoted string list from a named RON array field."""
    # Match: field: [\n  "name", "name", ...\n]
    # Handles multi-line arrays with comments inside.
    pat = re.compile(
        r'\b' + re.escape(field) + r'\s*:\s*\[([^\]]*)\]',
        re.DOTALL
    )
    m = pat.search(text)
    if not m:
        return []
    block = m.group(1)
    # Strip line comments before extracting quoted strings
    block = re.sub(r'//[^\n]*', '', block)
    return re.findall(r'"([^"]+)"', block)

# culture_id -> set of names (given + family, tracked separately for reporting)
given_by_culture = {}
family_by_culture = {}

for fpath in files:
    with open(fpath, 'r', encoding='utf-8') as f:
        text = f.read()
    # Extract culture id from the id: "..." field
    id_m = re.search(r'\bid\s*:\s*"([^"]+)"', text)
    culture_id = id_m.group(1) if id_m else os.path.basename(fpath)

    given_by_culture[culture_id] = set(extract_names_from_block(text, 'given_names'))
    family_by_culture[culture_id] = set(extract_names_from_block(text, 'family_names'))

cultures = list(given_by_culture.keys())
collisions_found = False

# Check given_names collisions
all_given_names = {}  # name -> list of cultures
for culture, names in given_by_culture.items():
    for name in names:
        all_given_names.setdefault(name, []).append(culture)

for name, cultures_with_name in sorted(all_given_names.items()):
    if len(cultures_with_name) > 1:
        collisions_found = True
        print(f"COLLISION given_names: \"{name}\" in {', '.join(sorted(cultures_with_name))}")

# Check family_names collisions
all_family_names = {}  # name -> list of cultures
for culture, names in family_by_culture.items():
    for name in names:
        all_family_names.setdefault(name, []).append(culture)

for name, cultures_with_name in sorted(all_family_names.items()):
    if len(cultures_with_name) > 1:
        collisions_found = True
        print(f"COLLISION family_names: \"{name}\" in {', '.join(sorted(cultures_with_name))}")

if not collisions_found:
    print(f"OK: no name collisions across {len(cultures)} culture(s): {', '.join(sorted(cultures))}")
    sys.exit(0)
else:
    sys.exit(1)
PYEOF
    exit $?
fi
# --- End name collision mode ----------------------------------------------

if [ $# -lt 2 ]; then
    echo "Usage: tooling/validate-ron <file.ron> <zone|zone_type|culture>"
    echo "       tooling/validate-ron --check-name-collisions <directory>"
    echo ""
    echo "Validates a RON file against the Rust struct schema."
    echo "Schema types:"
    echo "  zone_type — ZoneTypeTemplate (D-142 zone-type template)"
    echo "  zone      — ZoneSpec (legacy zone identity spec)"
    echo "  culture   — CultureProfile (culture profile)"
    echo ""
    echo "Name collision check:"
    echo "  --check-name-collisions <dir>  Scan culture-*.ron files for shared name pool entries"
    exit 1
fi

# Check file exists before resolving — realpath gives unhelpful errors otherwise
if [ ! -f "$1" ]; then
    echo "Error: file not found: $1"
    exit 1
fi

FILE="$(realpath "$1")"
SCHEMA="$2"

cd "$(dirname "$0")/../server"
exec cargo run --quiet --bin validate_ron -- "$FILE" "$SCHEMA"
