#!/bin/bash
#
# Compile the tmux-nerd-font-window-name icon table into a native tmux format.
#
# The plugin set automatic-rename-format to #(tmux-nerd-font-window-name ...),
# and every #() costs the tmux server a job: fork, environment copy, pipe. tmux
# re-checks window names constantly, so across ~140 windows this was one of the
# two hot paths in the server (job_run <- check_window_name in eu-stack
# samples); the other was the status line's own #() calls. Making the script
# itself fast did not help -- the cost is on the tmux side of the fork.
#
# This emits the same mapping as a pure #{...} format, so window names are
# computed inside tmux with no process at all. Output is identical to the
# plugin's script (checked name by name against it):
#   - icon looked up by #{pane_current_command}, fallback-icon when unknown
#   - "<multi-pane-icon> <icon>" when the window has more than one pane
#   - "<icon> <name>", except *vim / *python* / *reasonix* / *sh show the icon only
#
# Shape matters. tmux re-scans the rest of a #{?c,a,b} to find its commas at
# every level, so one flat 170-deep chain is quadratic: ~1.6ms per window for
# an unknown command, measured. Instead this dispatches on the first letter with
# a cheap glob (#{m:z*,...}) and only then compares names inside that bucket,
# so no lookup walks more than ~20 + ~15 short branches. No #{m/r:...} either:
# tmux recompiles a regex on every evaluation.
#
# The plugin must stay out of the tpm list: its loader rewrites
# automatic-rename-format from `run -b` and would overwrite this.
#
# Re-run after editing either YAML file:
#   ~/.tmux/scripts/gen-window-icons.sh && tmux source ~/.tmux/window-icons.conf

set -euo pipefail

DEFAULT_CONFIG="$HOME/.tmux/plugins/tmux-nerd-font-window-name/bin/defaults.yml"
USER_CONFIG="$HOME/.config/tmux/tmux-nerd-font-window-name.yml"
OUT="$HOME/.tmux/window-icons.conf"

cfg() {
    local v=null
    [ -f "$USER_CONFIG" ] && v=$(yq -r ".config[\"$1\"]" "$USER_CONFIG")
    [ "$v" = null ] && v=$(yq -r ".config[\"$1\"]" "$DEFAULT_CONFIG")
    [ "$v" = null ] && v=''
    printf '%s' "$v"
}

C='#{pane_current_command}'

# name<TAB>icon with user entries last so they win, then built into the
# bucketed format by awk. Entries that would break the format (, } # ' in a
# name or icon) are dropped with a warning; none of the shipped ones do.
icon_fmt=$(
    {
        yq -r '.icons // {} | to_entries | .[] | [.key, .value] | @tsv' "$DEFAULT_CONFIG"
        [ -f "$USER_CONFIG" ] && yq -r '.icons // {} | to_entries | .[] | [.key, .value] | @tsv' "$USER_CONFIG"
    } | awk -F'\t' -v C="$C" -v FB="$(cfg fallback-icon)" '
        $1 == "" { next }
        $0 ~ /[,}#\047]/ { print "skipping unsafe entry: " $1 > "/dev/stderr"; next }
        {
            if (!($1 in icon)) order[++n] = $1
            icon[$1] = $2
        }
        END {
            # one bucket per first character, in first-seen order
            for (i = 1; i <= n; i++) {
                k = order[i]; c = substr(k, 1, 1)
                if (!(c in bucket)) { bucket[c] = ""; corder[++m] = c }
                bucket[c] = bucket[c] SUBSEP k
            }
            out = FB
            for (j = m; j >= 1; j--) {
                c = corder[j]
                cnt = split(substr(bucket[c], 2), ks, SUBSEP)
                inner = FB
                for (i = cnt; i >= 1; i--)
                    inner = "#{?#{==:" C "," ks[i] "}," icon[ks[i]] "," inner "}"
                # glob metacharacters as a first letter would need escaping
                pat = (c ~ /[][*?\\]/) ? "\\" c "*" : c "*"
                out = "#{?#{m:" pat "," C "}," inner "," out "}"
            }
            print out
        }'
)

multi=$(cfg multi-pane-icon)
case $multi in *[,}#\']*) echo "ignoring unsafe multi-pane-icon" >&2; multi= ;; esac
[ -n "$multi" ] && icon_fmt="#{?#{>:#{window_panes},1},$multi ,}$icon_fmt"

if [ "$(cfg show-name)" = true ]; then
    # the plugin script: case $NAME in *vim|*python*|*reasonix*|*sh) icon only
    fmt="$icon_fmt#{?#{||:#{||:#{m:*vim,$C},#{m:*python*,$C}},#{||:#{m:*reasonix*,$C},#{m:*sh,$C}}},, $C}"
else
    fmt="$icon_fmt"
fi

{
    echo "## Generated by ~/.tmux/scripts/gen-window-icons.sh -- edit the YAML and re-run it."
    printf "set -g automatic-rename-format '%s'\n" "$fmt"
} > "$OUT"
echo "wrote $OUT (${#fmt} bytes)"
