#!/usr/bin/env bash
#
# plannotator-update — update Plannotator, then re-apply the local --gate --json
# patch that the installer overwrites.
#
# The upstream `plannotator-annotate` skill invokes the binary with no flags.
# Ryan runs `permissions.defaultMode: auto`, so the plugin's plan-review hook
# never fires and `/plannotator-annotate` is the only path to an Approve button.
# `--gate` adds that button; `--json` makes Close emit {"decision":"dismissed"}
# instead of empty stdout and lets approve-with-notes survive. Flags go *before*
# $ARGUMENTS so nothing the user types can swallow them as a value
# (--result-file is the only value-taking flag).
#
# Usage:
#   plannotator-update              # install latest, then patch
#   plannotator-update --patch-only # skip the download, just re-apply the patch
#   plannotator-update --check      # report patch state, change nothing

set -euo pipefail

INSTALL_URL="https://plannotator.ai/install.sh"
SKILL="${CLAUDE_CONFIG_DIR:-$HOME/.claude}/skills/plannotator-annotate/SKILL.md"

UNPATCHED='!`plannotator annotate $ARGUMENTS`'
PATCHED='!`plannotator annotate --gate --json $ARGUMENTS`'

MODE=install
case "${1-}" in
    --patch-only) MODE=patch ;;
    --check)      MODE=check ;;
    -h|--help)    awk 'NR==1{next} /^#/{sub(/^# ?/,""); print; next} {exit}' "$0" ; exit 0 ;;
    "")           ;;
    *)            echo "plannotator-update: unknown option '$1'" >&2 ; exit 2 ;;
esac

version() { command -v plannotator >/dev/null 2>&1 && plannotator --version 2>/dev/null || echo "(not installed)"; }

# --- update ---------------------------------------------------------------
if [ "$MODE" = install ]; then
    before=$(version)
    echo "==> Updating Plannotator (currently: $before)"
    # --yes keeps it unattended; the installer still honours the saved answers
    # in ~/.plannotator/install-prefs (extras=no, model_invocable=none).
    curl -fsSL "$INSTALL_URL" | bash -s -- --yes
    after=$(version)
    if [ "$before" = "$after" ]; then
        echo "==> Version unchanged: $after"
    else
        echo "==> Updated: $before -> $after"
    fi
fi

# --- patch ----------------------------------------------------------------
if [ ! -f "$SKILL" ]; then
    echo "plannotator-update: skill not found at $SKILL" >&2
    echo "  The installer should have written it. Nothing patched." >&2
    exit 1
fi

if grep -qxF "$PATCHED" "$SKILL"; then
    echo "==> Skill already patched (--gate --json present)"
    exit 0
fi

if [ "$MODE" = check ]; then
    echo "==> Skill is NOT patched. Invocation line(s) found:"
    grep -nF 'plannotator annotate' "$SKILL" >&2 || echo "  (none)" >&2
    exit 1
fi

if ! grep -qxF "$UNPATCHED" "$SKILL"; then
    # Upstream changed the invocation line. Refuse to guess — a wrong patch here
    # fails silently as a missing Approve button, which is exactly the bug this
    # script exists to prevent.
    echo "plannotator-update: cannot patch — expected invocation line not found." >&2
    echo "  expected: $UNPATCHED" >&2
    echo "  found in $SKILL:" >&2
    grep -nF 'plannotator annotate' "$SKILL" >&2 || echo "    (no 'plannotator annotate' line at all)" >&2
    echo "  Upstream likely reshaped the skill. Re-apply --gate --json by hand" >&2
    echo "  and update the OLD/NEW strings in $0." >&2
    exit 1
fi

tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
# Exact whole-line match, so no regex metacharacter can misfire on $ARGUMENTS.
awk -v old="$UNPATCHED" -v new="$PATCHED" '
    $0 == old { $0 = new; n++ }
    { print }
    END { exit(n ? 0 : 1) }
' "$SKILL" > "$tmp"
cat "$tmp" > "$SKILL"

grep -qxF "$PATCHED" "$SKILL" || { echo "plannotator-update: patch verification failed" >&2; exit 1; }
echo "==> Patched $SKILL"
echo "    $PATCHED"

# Note: ~/.agents/skills/plannotator-annotate is the "core" skill flavour — it has
# no inline-bash $ARGUMENTS line and is deliberately left alone.
