#!/usr/bin/env bash
#
# Install the Adom brand webfonts into code-server, so the EDITOR renders in brand type.
#
# Why a webfont and not a Windows font install: code-server renders inside HD's WebView2, so a
# font installed on Windows does resolve -- but that means every machine needs its own install
# step, and a machine that missed it silently falls back with nothing anywhere saying so. Serving
# the files from code-server itself means the browser fetches them over HTTP and a fresh machine
# needs no Windows install at all. This is the route that belongs in the golden image.
#
# Idempotent: re-running replaces the injected block rather than appending a second copy.
# NOT persistent across a code-server upgrade -- an upgrade rewrites workbench.html and drops the
# block, which is exactly why this runs from the bake and can be re-run by hand afterwards.
#
# Usage:  install-brand-fonts.sh [/path/to/woff2/dir]
#         defaults to the repo's static/fonts, then /opt/adom/fonts

set -euo pipefail

WB_DIR="${WB_DIR:-/usr/lib/code-server/lib/vscode/out/vs/code/browser/workbench}"
WB="$WB_DIR/workbench.html"
FONT_DIR="$WB_DIR/adom-fonts"
# The URL the browser fetches from. "/_static" is code-server's mount of its own install root
# (/usr/lib/code-server), so this mirrors $FONT_DIR minus the "/usr/lib/code-server" prefix.
FONT_URL="${FONT_URL:-/_static/lib/vscode/out/vs/code/browser/workbench/adom-fonts}"
SRC="${1:-}"

log() { echo "[brand-fonts] $*"; }
die() { echo "[brand-fonts] ERROR: $*" >&2; exit 1; }

[ -f "$WB" ] || die "workbench.html not found at $WB (is code-server installed?)"

# --- locate the source woff2 files -------------------------------------------------------------
if [ -z "$SRC" ]; then
    for c in "$(dirname "$0")/../static/fonts" /opt/adom/fonts "$HOME/.local/share/adom/fonts"; do
        [ -d "$c" ] && { SRC="$c"; break; }
    done
fi
[ -n "$SRC" ] && [ -d "$SRC" ] || die "no font source dir found (pass one as \$1)"
log "source: $SRC"

# --- the brand faces ---------------------------------------------------------------------------
# family|file|weight|style  -- weight may be a range ("400 700") for a variable font.
# Keep this table in sync with the brand guide: Familjen Grotesk headlines, Satoshi body,
# JetBrains Mono code.
FACES=(
    "Satoshi|Satoshi-Regular.woff2|400|normal"
    "Satoshi|Satoshi-Medium.woff2|500|normal"
    "Satoshi|Satoshi-Bold.woff2|700|normal"
    "Familjen Grotesk|FamiljenGrotesk-Variable.woff2|400 700|normal"
    "JetBrains Mono|JetBrainsMono-Regular.woff2|400|normal"
    "JetBrains Mono|JetBrainsMono-Italic.woff2|400|italic"
    "JetBrains Mono|JetBrainsMono-Bold.woff2|700|normal"
    "JetBrains Mono|JetBrainsMono-BoldItalic.woff2|700|italic"
)

# --- copy the files ----------------------------------------------------------------------------
mkdir -p "$FONT_DIR"
missing=0
for face in "${FACES[@]}"; do
    IFS='|' read -r _fam file _w _s <<<"$face"
    if [ -f "$SRC/$file" ]; then
        cp -f "$SRC/$file" "$FONT_DIR/$file"
    else
        log "MISSING $file -- it will be declared but will not load"
        missing=$((missing + 1))
    fi
done
# Ship the licences next to the fonts. The OFL requires the notice travel with the font.
for lic in "$SRC"/*OFL*.txt "$SRC"/*LICENSE*; do
    [ -f "$lic" ] && cp -f "$lic" "$FONT_DIR/"
done
log "copied $(( ${#FACES[@]} - missing ))/${#FACES[@]} faces into $FONT_DIR"

# --- build the <style> block -------------------------------------------------------------------
BLOCK="$(mktemp)"
{
    echo '<!--ADOM-FONTS-->'
    echo '<style>'
    echo '/* Adom brand webfonts, served BY code-server from the golden image.'
    echo '   No Windows font install needed: the browser fetches these over HTTP, which is why a font'
    echo '   named here resolves even on a machine that has never seen it.'
    echo '   The URL is deliberate. A relative "./adom-fonts/x.woff2" resolves against the PAGE url'
    echo '   ("/?folder=/home/adom/project"), i.e. "/adom-fonts/x.woff2", which 404s -- a font declared'
    echo '   that way never loads, and you cannot tell because a Windows-installed font of the same'
    echo '   name silently covers for it. "/_static/" maps to the code-server install root and carries'
    echo '   no commit hash, so unlike the "stable-<sha>/static/" route it survives an upgrade.'
    echo '   Generated by scripts/install-brand-fonts.sh. */'
    for face in "${FACES[@]}"; do
        IFS='|' read -r fam file w s <<<"$face"
        printf "@font-face{font-family:'%s';src:url('%s/%s') format('woff2');font-weight:%s;font-style:%s;font-display:swap}\n" \
            "$fam" "$FONT_URL" "$file" "$w" "$s"
    done
    echo '</style>'
    echo '<!--/ADOM-FONTS-->'
} >"$BLOCK"

# --- strip any previous block, then insert -----------------------------------------------------
# Strip-then-insert, never append: appending is how you end up with three stale copies fighting.
python3 - "$WB" "$BLOCK" <<'PY'
import re, sys, io
wb_path, block_path = sys.argv[1], sys.argv[2]
html = io.open(wb_path, encoding='utf-8').read()
block = io.open(block_path, encoding='utf-8').read().rstrip('\n')

html, n = re.subn(r'<!--ADOM-FONTS-->.*?<!--/ADOM-FONTS-->\n?', '', html, flags=re.S)

# Inject into <head> so the faces are declared before the workbench paints.
if '</head>' in html:
    html = html.replace('</head>', block + '\n</head>', 1)
else:
    html = html.rstrip() + '\n' + block + '\n'

io.open(wb_path, 'w', encoding='utf-8').write(html)
print(f"[brand-fonts] removed {n} previous block(s), injected 1")
PY
rm -f "$BLOCK"

# --- verify by FETCHING, not by trusting the copy ----------------------------------------------
# document.fonts.check() is not proof: it returns true for a Windows-installed font just as
# readily as for a webfont, so it cannot tell you whether this install actually works.
fail=0
for face in "${FACES[@]}"; do
    IFS='|' read -r _fam file _w _s <<<"$face"
    [ -s "$FONT_DIR/$file" ] || { log "VERIFY FAIL: $file absent or empty"; fail=1; }
done
grep -q "<!--ADOM-FONTS-->" "$WB" || { log "VERIFY FAIL: block not present in workbench.html"; fail=1; }

# Fetch each face over HTTP, exactly as the browser will. This is the check that matters: a
# declared font whose URL 404s looks completely fine on disk, and a Windows-installed font of the
# same name covers for it so the editor still looks right. Only the fetch can tell you.
CS_PORT="${CS_PORT:-$(ps -eo args | grep -oP '(?<=--bind-addr )[0-9.]+:\K[0-9]+' | head -1)}"
CS_PORT="${CS_PORT:-8080}"
if command -v curl >/dev/null 2>&1; then
    log "verifying over HTTP on port $CS_PORT"
    for face in "${FACES[@]}"; do
        IFS='|' read -r _fam file _w _s <<<"$face"
        code=$(curl -s -m 8 -o /tmp/.bf.$$ -w '%{http_code}' "http://127.0.0.1:$CS_PORT$FONT_URL/$file" || echo 000)
        magic=$(head -c4 /tmp/.bf.$$ 2>/dev/null || true)
        if [ "$code" = "200" ] && [ "$magic" = "wOF2" ]; then
            log "  OK  $file (http $code, woff2)"
        else
            log "  FAIL $file (http $code, magic '${magic}') -- the browser will NOT load this"
            fail=1
        fi
        rm -f /tmp/.bf.$$
    done
else
    log "curl absent; skipped the HTTP check (files copied, but UNPROVEN)"
fi

[ "$fail" = 0 ] || die "verification failed"

log "OK -- $(ls -1 "$FONT_DIR"/*.woff2 | wc -l) woff2 served from $FONT_DIR"
log "code-server must be restarted (or the editor hard-reloaded) to pick up workbench.html"
