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

# Portable across bash 3.2+ (macOS stock /bin/bash) and bash 4+ (Linux, Homebrew).
# Avoids `declare -A` so the script runs on a fresh macOS without `brew install bash`.

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
REPO_FONT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)/assets/fonts"

# Download target lives OUTSIDE the skill directory on purpose.
#
# Claude Desktop skill ZIPs exclude the large bundled fonts (TsangerJinKai TTFs,
# Source Han Serif K OTFs). The old code downloaded them back into the skill's
# own assets/fonts, which pushed the installed skill past Claude Desktop's size
# limit ("upload/execution too big"). We instead drop them in the XDG user font
# dir, which fontconfig scans by default on both macOS (Homebrew) and Linux, yet
# does NOT show up in macOS Font Book. WeasyPrint then resolves "TsangerJinKai02"
# / "Source Han Serif K" from here when the template's relative @font-face path
# is absent; online renders still fall back to the jsDelivr URL baked alongside
# each @font-face declaration.
FONT_DIR="${KAMI_FONT_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/fonts/kami}"

MIN_SIZE_CN=10000000  # 10MB for TsangerJinKai (large CJK glyph set)
MIN_SIZE_KO=6500000   # 6.5MB for Source Han Serif K (Adobe full subset)

# TsangerJinKai (CN): index N pairs CN_NAMES[N] with CN_LOCAL_NAMES[N].
CN_NAMES=("仓耳今楷02-W04.ttf" "仓耳今楷02-W05.ttf")
CN_LOCAL_NAMES=("TsangerJinKai02-W04.ttf" "TsangerJinKai02-W05.ttf")

# Source Han Serif K (KO): mirror filenames match the repo filenames, so there
# is no rename step (unlike Tsanger's Chinese-named official downloads).
KO_NAMES=("SourceHanSerifKR-Regular.otf" "SourceHanSerifKR-Medium.otf")

# Mirror order is intentionally jsdmirror-first here, opposite of the
# templates' @font-face fallback (which lists jsdelivr first). Reasoning:
# this script runs interactively when fonts are missing locally, often from
# China where jsdmirror is reachable and faster than jsdelivr; templates run
# anywhere and prioritize jsdelivr's broader global coverage.
MIRROR_SOURCES=(
  "https://cdn.jsdmirror.com/gh/tw93/Kami@main/assets/fonts"
  "https://cdn.jsdelivr.net/gh/tw93/Kami@main/assets/fonts"
)

check_size() {
  local file="$1"
  local min_size="$2"
  [[ -f "$file" ]] || return 1
  local size
  size=$(wc -c < "$file" | tr -d ' ')
  [[ "$size" -ge "$min_size" ]]
}

cn_present_in() {
  local dir="$1" name
  for name in "${CN_LOCAL_NAMES[@]}"; do
    check_size "$dir/$name" "$MIN_SIZE_CN" || return 1
  done
  return 0
}

ko_present_in() {
  local dir="$1" name
  for name in "${KO_NAMES[@]}"; do
    check_size "$dir/$name" "$MIN_SIZE_KO" || return 1
  done
  return 0
}

refresh_fontconfig() {
  # The XDG font dir is already on fontconfig's default scan path, so a cache
  # refresh is all that is needed for WeasyPrint to pick the fonts up. Optional:
  # absence of fc-cache (e.g. minimal sandbox) is non-fatal, fontconfig rescans
  # the directory lazily on next use.
  if command -v fc-cache >/dev/null 2>&1; then
    fc-cache -f "$FONT_DIR" >/dev/null 2>&1 || true
  fi
}

download_tsanger() {
  local cn_name="$1"
  local local_name="$2"
  local target="$FONT_DIR/$local_name"

  # Source 1: official tsanger.cn
  local official_url="https://tsanger.cn/download/${cn_name}"
  echo "  Trying: tsanger.cn (official)"
  if curl --retry 2 --connect-timeout 15 --max-time 300 -fSL "$official_url" -o "$target.tmp" 2>/dev/null; then
    if check_size "$target.tmp" "$MIN_SIZE_CN"; then
      mv "$target.tmp" "$target"
      echo "  OK: $local_name downloaded ($(du -h "$target" | cut -f1))"
      return 0
    else
      rm -f "$target.tmp"
    fi
  else
    rm -f "$target.tmp"
  fi

  # Source 2+: CDN mirrors (already named TsangerJinKai02-W0x.ttf)
  for src in "${MIRROR_SOURCES[@]}"; do
    local url="$src/$local_name"
    echo "  Trying: $url"
    if curl --retry 2 --connect-timeout 15 --max-time 300 -fSL "$url" -o "$target.tmp" 2>/dev/null; then
      if check_size "$target.tmp" "$MIN_SIZE_CN"; then
        mv "$target.tmp" "$target"
        echo "  OK: $local_name downloaded ($(du -h "$target" | cut -f1))"
        return 0
      else
        rm -f "$target.tmp"
      fi
    else
      rm -f "$target.tmp"
    fi
  done

  echo "  ERROR: all sources failed for $local_name"
  return 1
}

download_ko_serif() {
  local local_name="$1"
  local target="$FONT_DIR/$local_name"

  # CDN mirrors only: Source Han Serif K has no single official direct-download
  # URL, so we serve the committed OTFs from the same jsDelivr/jsdmirror gh path.
  for src in "${MIRROR_SOURCES[@]}"; do
    local url="$src/$local_name"
    echo "  Trying: $url"
    if curl --retry 2 --connect-timeout 15 --max-time 300 -fSL "$url" -o "$target.tmp" 2>/dev/null; then
      if check_size "$target.tmp" "$MIN_SIZE_KO"; then
        mv "$target.tmp" "$target"
        echo "  OK: $local_name downloaded ($(du -h "$target" | cut -f1))"
        return 0
      else
        rm -f "$target.tmp"
      fi
    else
      rm -f "$target.tmp"
    fi
  done

  echo "  ERROR: all sources failed for $local_name"
  return 1
}

# A repo checkout ships the committed font files. Templates resolve their
# relative `../fonts/*` @font-face path against them directly, so there is
# nothing to download or register. These branches are skipped inside a Claude
# Desktop skill, whose assets/fonts has the large fonts stripped out.

cn_failed=0
if cn_present_in "$REPO_FONT_DIR"; then
  echo "OK: TsangerJinKai fonts present in repo checkout ($REPO_FONT_DIR)"
else
  mkdir -p "$FONT_DIR"
  if cn_present_in "$FONT_DIR"; then
    echo "OK: TsangerJinKai fonts present ($FONT_DIR)"
  else
    echo "Downloading TsangerJinKai fonts to $FONT_DIR ..."
    for i in "${!CN_NAMES[@]}"; do
      cn_name="${CN_NAMES[$i]}"
      local_name="${CN_LOCAL_NAMES[$i]}"
      if check_size "$FONT_DIR/$local_name" "$MIN_SIZE_CN"; then
        echo "  OK: $local_name already present"
        continue
      fi
      if ! download_tsanger "$cn_name" "$local_name"; then
        cn_failed=$((cn_failed + 1))
      fi
    done
    if [[ "$cn_failed" -gt 0 ]]; then
      echo ""
      echo "Some TsangerJinKai files could not be downloaded. Alternatives:"
      echo "  1. Install Source Han Serif SC: brew install --cask font-source-han-serif-sc"
      echo "  2. Copy TsangerJinKai02-W04.ttf and W05.ttf manually into $FONT_DIR"
      # Don't exit yet, try the KO recovery too so a Korean-only user still gets KO fonts.
    fi
  fi
fi

ko_failed=0
if ko_present_in "$REPO_FONT_DIR"; then
  echo "OK: Source Han Serif K fonts present in repo checkout ($REPO_FONT_DIR)"
else
  mkdir -p "$FONT_DIR"
  if ko_present_in "$FONT_DIR"; then
    echo "OK: Source Han Serif K fonts present ($FONT_DIR)"
  else
    echo "Downloading Source Han Serif K fonts to $FONT_DIR ..."
    for local_name in "${KO_NAMES[@]}"; do
      if check_size "$FONT_DIR/$local_name" "$MIN_SIZE_KO"; then
        echo "  OK: $local_name already present"
        continue
      fi
      if ! download_ko_serif "$local_name"; then
        ko_failed=$((ko_failed + 1))
      fi
    done
    if [[ "$ko_failed" -gt 0 ]]; then
      echo ""
      echo "Some Source Han Serif K files could not be downloaded. Alternatives:"
      echo "  1. Download from https://github.com/adobe-fonts/source-han-serif/releases"
      echo "  2. Copy SourceHanSerifKR-Regular.otf and -Medium.otf manually into $FONT_DIR"
    fi
  fi
fi

if [[ "$cn_failed" -gt 0 || "$ko_failed" -gt 0 ]]; then
  exit 1
fi

refresh_fontconfig
echo "OK: all fonts ready"
