#!/bin/sh
# Installed by `vibey-gh install` — do not edit; edit the template in vibey-gh.
#
# Appends the provenance trailer to any commit message that lacks it, so the rule holds
# locally without anyone having to remember it. CI enforces the same trailer, so a commit
# made without this hook fails the pull request rather than slipping through.


# Resolve the CLI. `vibey-gh` on PATH is the normal case, but a project virtualenv that
# has not been activated is just as normal — and a gate that reports "not installed"
# when the tool IS installed is a gate people learn to bypass. Look where it actually
# lives before giving up. Hooks run from the top of the working tree.
# Where this repository's own copy of vibey-gh lives, printed as a directory — or
# nothing, which is the ordinary case for a repository that merely adopted it.
#
# What is looked for is the pyproject that DECLARES the distribution, not a fixed path.
# It sits at the top of the tree in the standalone repository and under `src/` in the
# monorepo that absorbed it, and hard-coding either one breaks the other. `git ls-files`
# keeps the search bounded to tracked files, so a vendored copy under `.venv/` or
# `site/` can never match, and it is available here by definition: hooks run inside a
# git repository, from the top of the working tree.
vibey_gh_self() {
  # Read from `[install] self_source` in .vibey-gh.toml at runtime rather than rendered
  # in: `install.installed()` compares these hooks byte-for-byte against the template, so
  # a substituted hook would be permanently "out of date" and refuse every push.
  #
  # A DECLARED path, never a search. Searching the tree for a pyproject that declares
  # `name = "vibey-gh"` reads whatever is in the working tree, which on a contributor's
  # branch is whatever they put there -- and this hook executes what it finds.
  dir=$(sed -n 's/^[[:space:]]*self_source[[:space:]]*=[[:space:]]*"\(.*\)".*/\1/p' \
    .vibey-gh.toml 2>/dev/null | head -n 1)
  [ -n "$dir" ] || dir=.
  case "$dir" in /*|*..*) return 0 ;; esac
  grep -qE '^name = "vibey-gh"' "$dir/pyproject.toml" 2>/dev/null || return 0
  [ -d "$dir/vibey_gh" ] || return 0
  printf '%s' "$dir"
}


vibey_gh() {
  # A repository that CARRIES vibey-gh must run that source, never an installed copy.
  # Its `develop` is ahead of the last release nearly always, so a globally installed
  # vibey-gh compares the repository's managed assets against the older ones it bundles,
  # reports them out of date, and refuses every push — a contributor who installed the
  # tool the obvious way cannot commit to it. The package is dependency-free stdlib, so
  # `python3 -m` against the checkout needs no install and no virtualenv at all.
  if [ -z "${_VIBEY_GH_SELF+x}" ]; then
    _VIBEY_GH_SELF=$(vibey_gh_self)
  fi
  # Every `python3` below runs with PYTHONSAFEPATH=1. Without it, `-c` and `-m` put the
  # current directory -- the top of the working tree -- first on sys.path, so a checked-out
  # branch carrying a `vibey_gh/` package of its own would be imported and executed by
  # this hook in place of the real one. The self-hosted branch still runs its source: it
  # names that source on PYTHONPATH, which PYTHONSAFEPATH leaves alone. Python 3.11+
  # honours the variable and older interpreters ignore it; vibey-gh requires 3.11.
  if [ -n "$_VIBEY_GH_SELF" ] && PYTHONSAFEPATH=1 \
      PYTHONPATH="$_VIBEY_GH_SELF${PYTHONPATH:+:$PYTHONPATH}" \
      python3 -c "import vibey_gh.cli" >/dev/null 2>&1; then
    PYTHONSAFEPATH=1 PYTHONPATH="$_VIBEY_GH_SELF${PYTHONPATH:+:$PYTHONPATH}" \
      python3 -m vibey_gh.cli "$@"
  elif command -v vibey-gh >/dev/null 2>&1; then
    vibey-gh "$@"
  elif [ -n "${VIRTUAL_ENV:-}" ] && [ -x "${VIRTUAL_ENV}/bin/vibey-gh" ]; then
    "${VIRTUAL_ENV}/bin/vibey-gh" "$@"
  elif [ -x ".venv/bin/vibey-gh" ]; then
    ./.venv/bin/vibey-gh "$@"
  elif [ -x "venv/bin/vibey-gh" ]; then
    ./venv/bin/vibey-gh "$@"
  elif PYTHONSAFEPATH=1 python3 -c "import vibey_gh.cli" >/dev/null 2>&1; then
    PYTHONSAFEPATH=1 python3 -m vibey_gh.cli "$@"
  elif PYTHONSAFEPATH=1 python3 -c "import vibey_bootstrap.gh.cli" >/dev/null 2>&1; then
    PYTHONSAFEPATH=1 python3 -m vibey_bootstrap.gh.cli "$@"   # pre-split layout
  else
    return 127
  fi
}


msg_file="$1"
key=$(vibey_gh trailer-key 2>/dev/null || echo "Made-With")
trailer=$(vibey_gh trailer 2>/dev/null || echo "Made-With: Made with ❤️ by [Vibey](https://the-vibey-project.github.io/vibey/), Developed by [Adam Matthew Steinberger](https://vibewithadam.matthewsteinberger.com/) ([@adammatthewsteinberger](https://github.com/adammatthewsteinberger/)).")

# A pre-existing project hook runs first and may do its own thing -- including refuse the
# commit, and that refusal must stand. This hook runs without `set -e`, so the chain has to
# carry the status out itself: a bare `[ -x … ] && "…"` discarded it, and a project hook
# that rejected the message was ignored while the commit went ahead.
if [ -x "$(dirname "$0")/commit-msg.local" ]; then
  "$(dirname "$0")/commit-msg.local" "$@" || exit $?
fi

# Normalize the subject without assuming the Python package is importable in the hook's
# process. The body and existing trailers remain unchanged.
subject=$(sed -n '1p' "$msg_file")
if [ -n "$subject" ] && ! printf '%s\n' "$subject" | grep -Eq '^[a-z][a-z0-9-]*(\([a-z0-9][a-z0-9._/-]*\))?!?: [^[:space:]].*$'; then
  tmp="${msg_file}.vibey-gh.tmp"
  { printf 'chore: %s\n' "$subject"; sed '1d' "$msg_file"; } > "$tmp"
  mv "$tmp" "$msg_file"
fi

# Already present in any case — nothing to do.
if grep -qiE "^${key}:[[:space:]]*[^[:space:]]" "$msg_file"; then
  exit 0
fi

# A comment-only or empty message means an aborted commit; leave it alone.
if ! grep -qvE '^\s*(#.*)?$' "$msg_file"; then
  exit 0
fi

printf '\n%s\n' "$trailer" >> "$msg_file"
