#!/usr/bin/env bash
# Packs the town kit for OhMyGames builds: dist/townkit.tar.gz (code, into src/lib/town) and
# dist/townkit-<style>.tar.gz (models + textures, into public/town). Writes dist/townkit.sha.
set -euo pipefail

ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
DIST="$ROOT/dist"
KITS="$ROOT/browse/kits"
BUILDING="$ROOT/omg/kit/building"
WARN_MB=25
STAGE="$(mktemp -d "/tmp/w-factory-pack-XXXXXX")"
trap 'rm -rf "$STAGE"' EXIT

MEDIEVAL_KITS="medieval medieval-trades medieval-town medieval-town-v2 medieval-church medieval-cathedral medieval-walls"
BRETON_KITS="breton medieval-church medieval-walls"  # church/walls share textures from ../medieval/: packed by reference

mkdir -p "$DIST"

warn() { echo "WARN: $*" >&2; }

# code tarball: the building modules, styles, guides (no tests)
CODE="$STAGE/code"
mkdir -p "$CODE/styles"
shopt -s nullglob
modules=("$BUILDING"/*.mjs)
shopt -u nullglob
if [ "${#modules[@]}" -eq 0 ]; then
  echo "no building modules under $BUILDING" >&2
  exit 1
fi
cp "${modules[@]}" "$CODE/"
# Dressing reuses FGE's MIT tree/grass module. Keep the whole closed import set, including embedded pictures and notice.
mkdir -p "$CODE/vendor/fge-look"
cp "$ROOT"/browse/vendor/fge-look/*.mjs "$ROOT"/browse/vendor/fge-look/PROVENANCE.md "$CODE/vendor/fge-look/"
sed -i "s|../../../browse/vendor/fge-look/|./vendor/fge-look/|g" "$CODE/dress-render.mjs" "$CODE/town-grass.mjs"
cp "$BUILDING"/styles/*.mjs "$CODE/styles/"
for doc in TYPES.md SETTLEMENT.md TOWN.md; do
  if [ -f "$BUILDING/$doc" ]; then
    cp "$BUILDING/$doc" "$CODE/"
  else
    warn "$doc is missing from $BUILDING (the builder contract points at it)"
  fi
done
for f in settlement.mjs settlement-render.mjs landmarks.mjs; do
  [ -f "$BUILDING/$f" ] || warn "$f not present yet (SETTLEMENT.md API not in the kit)"
done
tar --sort=name --mtime=@0 --owner=0 --group=0 --numeric-owner -czf "$DIST/townkit.tar.gz" -C "$CODE" .
sha256sum "$DIST/townkit.tar.gz" | cut -d' ' -f1 > "$DIST/townkit.sha"

# models tarballs: one per style family, each kit as town/kits/<kit>/ with its textures
pack_style() {
  local style="$1"; shift
  local out="$STAGE/$style"
  local found=0
  for kit in "$@"; do
    local src="$KITS/$kit"
    if [ ! -d "$src" ]; then
      warn "$style: kit '$kit' not in browse/kits yet, skipped"
      continue
    fi
    found=$((found + 1))
    local dst="$out/town/kits/$kit"
    mkdir -p "$dst"
    python3 - "$src" "$dst" <<'PY'
import json, pathlib, shutil, sys

src, dst = map(pathlib.Path, sys.argv[1:3])
for name in ("kit.glb", "kit_lite.glb", "kit.json", "materials.json", "style.json"):
    if (src / name).is_file():
        shutil.copy2(src / name, dst / name)
    else:
        print(f"WARN: {src.name}/{name} missing", file=sys.stderr)
kit = json.loads((src / "kit.json").read_text())
for extra in kit.get("extra_files", []):
    if (src / extra).is_file():
        shutil.copy2(src / extra, dst / extra)
    else:
        print(f"WARN: {src.name} extra_file {extra} missing", file=sys.stderr)
mats = json.loads((src / "materials.json").read_text())
refs = set()
def walk(node):
    if isinstance(node, dict):
        for v in node.values():
            walk(v)
    elif isinstance(node, list):
        for v in node:
            walk(v)
    elif isinstance(node, str) and (node.startswith("materials/") or (node.startswith("../") and "/materials/" in node)):
        # "../medieval/materials/x.ktx2": a family kit's shared texture (dedupe_shelf.py), packed at its own kit path
        refs.add(node)
walk(mats)
for rel in sorted(refs):
    if (src / rel).is_file():
        (dst / rel).parent.mkdir(parents=True, exist_ok=True)
        shutil.copy2(src / rel, dst / rel)
    else:
        print(f"WARN: {src.name} references {rel} but it is not on disk", file=sys.stderr)
PY
  done
  if [ "$found" -eq 0 ]; then
    warn "$style: no kits packed, townkit-$style.tar.gz not written"
    return 0
  fi
  mkdir -p "$out/town/basis" && cp "$ROOT"/omg/public/basis/basis_transcoder.* "$out/town/basis/"  # KTX2 shelf decoder
  # authored hero houses (round 6, heroes.mjs loadHeroKit): one KTX2 + Draco GLB, plus the Draco decoder it needs
  if [ "$style" = medieval ] && [ -f "$KITS/medieval-heroes/medieval-hero-houses.glb" ]; then
    mkdir -p "$out/town/kits/medieval-heroes" "$out/town/draco"
    cp "$KITS/medieval-heroes/medieval-hero-houses.glb" "$out/town/kits/medieval-heroes/"
    cp "$ROOT"/browse/vendor/addons/libs/draco/gltf/* "$out/town/draco/" 2>/dev/null || warn "draco decoder files missing"
  fi
  tar --sort=name --mtime=@0 --owner=0 --group=0 --numeric-owner -czf "$DIST/townkit-$style.tar.gz" -C "$out" .
  local bytes
  bytes=$(stat -c %s "$DIST/townkit-$style.tar.gz")
  if [ "$bytes" -gt $((WARN_MB * 1024 * 1024)) ]; then
    warn "townkit-$style.tar.gz is $((bytes / 1024 / 1024)) MB, over $WARN_MB MB"
  fi
}

pack_style medieval $MEDIEVAL_KITS
pack_style breton $BRETON_KITS

echo "sizes:"
for f in "$DIST"/townkit.tar.gz "$DIST"/townkit-*.tar.gz; do
  [ -f "$f" ] && printf '  %8d bytes  %s\n' "$(stat -c %s "$f")" "$(basename "$f")"
done
echo "sha256 $(cat "$DIST/townkit.sha")  townkit.tar.gz"
