#!/bin/sh
# Install loopgate hooks into a repo's .githooks without clobbering existing hooks.
set -eu

source_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
target_dir=.githooks
if [ "$source_dir" = "$(CDPATH= cd -- "$target_dir" 2>/dev/null && pwd)" ]; then
    exit 0
fi
cp "$source_dir/_resolve" "$target_dir/_resolve"

for name in pre-commit pre-push prepare-commit-msg; do
    source=$source_dir/$name
    hook=$target_dir/$name
    legacy_hook=$target_dir/loopgate-$name
    legacy_call="\"\$(dirname \"\$0\")/loopgate-$name\" \"\$@\" || exit # loopgate"
    case $name in
        pre-commit) command='exec "$HARNESS" preflight' ;;
        pre-push) command='exec "$HARNESS" gate' ;;
        prepare-commit-msg) command='exec "$HARNESS" prepare-commit-msg "$@"' ;;
    esac
    if [ -e "$hook" ] && grep -Fqx "$legacy_call" "$hook"; then
        tmp=$(mktemp "$target_dir/.hoist.XXXXXX")
        grep -Fvx "$legacy_call" "$hook" > "$tmp"
        mv "$tmp" "$hook"
        if [ "$(wc -l < "$hook")" -eq 1 ] && [ "$(head -n 1 "$hook")" = '#!/bin/sh' ]; then
            cp "$source" "$hook"
        fi
    fi
    rm -f "$legacy_hook"
    if [ ! -e "$hook" ]; then
        cp "$source" "$hook"
    elif ! cmp -s "$source" "$hook" && ! grep -Fqx ') || exit # loopgate' "$hook"; then
        case $(head -n 1 "$hook") in "#!"*sh*) ;; *) echo "hoist: $hook is not a shell hook" >&2; exit 1 ;; esac
        tmp=$(mktemp "$target_dir/.hoist.XXXXXX")
        {
            IFS= read -r first
            printf '%s\n%s\n%s\n%s\n%s\n' \
                "$first" '(' '    . "$(dirname "$0")/_resolve"' "    $command" ') || exit # loopgate'
            cat
        } < "$hook" > "$tmp"
        mv "$tmp" "$hook"
    fi
    chmod +x "$hook"
done
