#!/bin/bash
# Adapts real application/tray icons on the target host into flat,
# single-color silhouettes matching svg_samples/style_guide.json (see
# 09-build-icon-style-guide.sh), and saves the result INTO THIS REPO at
# generated_icons/silhouettes/ -- not just on the target. That's the
# portable, expensive-once artifact: to light up the same icon set on a
# fresh CachyOS install, you don't need potrace or to re-trace anything,
# just run 11-deploy-icon-theme.sh against it.
#
# Candidates = every Icon= from installed .desktop files (covers the app
# launcher, and any future taskbar/dock) + the curated tray/status names in
# tray-icon-candidates.txt (NetworkManager, bluetooth, volume, battery, ...
# aren't desktop-entry driven).
#
# Idempotent: generated_icons/manifest.json remembers each icon's resolved
# source file hash and the style guide's hash, so a rerun (e.g. after
# installing a new app) only traces what's actually new or changed.
# --force/--force-all re-traces regardless.
#
# This script does NOT apply any color -- the silhouettes it writes contain
# the literal placeholder "__ACCENT__" where the accent color goes. Run
# 11-deploy-icon-theme.sh afterwards (or after any theme/wallpaper switch)
# to stamp the current accent and install into the target's icon theme.
#
# Usage: 10-generate-app-icons.sh --vm [--force <icon-name> ...] [--force-all]
#   --vm only -- this reads ../svg_samples/style_guide.json, which only
#   exists in this dev-host checkout (a laptop deploy deliberately leaves
#   svg_samples/ behind, see README.md), and writes its output straight
#   into THIS repo's generated_icons/ -- running it against a laptop
#   wouldn't trace that laptop's extra apps into the shared cache anyway,
#   just into a copy of the repo nobody else sees. Trace new apps by
#   adding them to the VM (same ML4W profile) and running this against
#   --vm, then ship the updated cache to the laptop via
#   18-deploy-theme-artifacts.sh / deploy.sh like any other icon update.
set -euo pipefail
cd "$(dirname "${BASH_SOURCE[0]}")"
source ./00-config.sh

FORCE_NAMES=()
FORCE_ALL=0
parse_target_flag "$@"
set -- "${PARSED_ARGS[@]+"${PARSED_ARGS[@]}"}"
while [ $# -gt 0 ]; do
    case "$1" in
        --force-all) FORCE_ALL=1 ;;
        --force) shift; FORCE_NAMES+=("$1") ;;
        *) echo "Unknown argument: $1" >&2; exit 1 ;;
    esac
    shift
done

if [ "$TARGET" = "local" ]; then
    echo "10-generate-app-icons.sh is --vm only -- see the usage comment at the top" >&2
    echo "of this file for why. Run against --vm instead." >&2
    exit 1
fi

STYLE_GUIDE="../svg_samples/style_guide.json"
if [ ! -f "$STYLE_GUIDE" ]; then
    echo "Missing ${STYLE_GUIDE} -- run ./09-build-icon-style-guide.sh first." >&2
    exit 1
fi

GEN_DIR="../generated_icons"
SILHOUETTE_DIR="${GEN_DIR}/silhouettes"
MANIFEST="${GEN_DIR}/manifest.json"
mkdir -p "$SILHOUETTE_DIR"

WORK=$(mktemp -d)
trap 'rm -rf "$WORK"' EXIT

echo ">>> Target: ${TARGET}"

python3 -c "import hashlib; print(hashlib.sha256(open('${STYLE_GUIDE}','rb').read()).hexdigest())" \
    > "${WORK}/style_guide.sha256"
ALPHAMAX=$(python3 -c "import json; print(json.load(open('${STYLE_GUIDE}'))['potrace_alphamax'])")
PADDING=$(python3 -c "import json; print(json.load(open('${STYLE_GUIDE}'))['padding_ratio'])")

REMOTE_WORKDIR='$HOME/.config/timhyperland-icons'
REMOTE_ICON_PY="${REMOTE_WORKDIR}/icon_remote.py"
REMOTE_TRAY="${REMOTE_WORKDIR}/tray-icon-candidates.txt"
REMOTE_JOBS="${REMOTE_WORKDIR}/jobs.json"
REMOTE_OUTDIR="${REMOTE_WORKDIR}/silhouettes-out"

echo ">>> [1/5] Ensuring potrace is installed on the target"
if ! run "command -v potrace >/dev/null 2>&1"; then
    run "echo '${VM_PASSWORD}' | sudo -S pacman -S --needed --noconfirm potrace >/dev/null"
fi

echo ">>> [2/5] Uploading resolver/tracer and candidate list"
run "mkdir -p ${REMOTE_WORKDIR}"
run "cat > ${REMOTE_ICON_PY}" < ./lib/icon_remote.py
run "cat > ${REMOTE_TRAY}" < ./tray-icon-candidates.txt

echo ">>> [3/5] Resolving candidates on the target (desktop entries + tray list)"
run "python3 ${REMOTE_ICON_PY} resolve --tray-list ${REMOTE_TRAY}" > "${WORK}/resolved.jsonl"

FORCE_ARGS=()
for n in "${FORCE_NAMES[@]+"${FORCE_NAMES[@]}"}"; do
    FORCE_ARGS+=(--force "$n")
done
[ "$FORCE_ALL" = 1 ] && FORCE_ARGS+=(--force-all)

python3 ./lib/icon_local.py plan \
    --resolve-output "${WORK}/resolved.jsonl" \
    --manifest "$MANIFEST" \
    --style-guide-hash "${WORK}/style_guide.sha256" \
    --silhouette-dir "$SILHOUETTE_DIR" \
    --jobs-out "${WORK}/jobs.json" \
    --resolved-out "${WORK}/resolved.json" \
    "${FORCE_ARGS[@]+"${FORCE_ARGS[@]}"}"

JOB_COUNT=$(python3 -c "import json; print(len(json.load(open('${WORK}/jobs.json'))))")

if [ "$JOB_COUNT" -eq 0 ]; then
    echo ">>> Nothing to (re)generate."
    exit 0
fi

echo ">>> [4/5] Tracing ${JOB_COUNT} icon(s) on the target (potrace alphamax=${ALPHAMAX}, padding=${PADDING})"
run "cat > ${REMOTE_JOBS}" < "${WORK}/jobs.json"
run "rm -rf ${REMOTE_OUTDIR} && mkdir -p ${REMOTE_OUTDIR} && python3 ${REMOTE_ICON_PY} trace \
    --jobs ${REMOTE_JOBS} --outdir ${REMOTE_OUTDIR} --alphamax ${ALPHAMAX} --padding-ratio ${PADDING}"

echo ">>> [5/5] Pulling generated silhouettes back into ${SILHOUETTE_DIR}"
run "tar -C ${REMOTE_OUTDIR} -cf - . | base64 -w0" > "${WORK}/silhouettes.tar.b64"
base64 -d < "${WORK}/silhouettes.tar.b64" | tar -C "$SILHOUETTE_DIR" -xf -

python3 ./lib/icon_local.py commit \
    --jobs "${WORK}/jobs.json" \
    --manifest "$MANIFEST" \
    --style-guide-hash "${WORK}/style_guide.sha256" \
    --silhouette-dir "$SILHOUETTE_DIR"

echo ">>> Done. Run ./11-deploy-icon-theme.sh to stamp the current accent color and install."
