#!/usr/bin/env bash

set -euo pipefail

SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd -- "${SCRIPT_DIR}/.." && pwd)"
ANI_BIN="${PROJECT_ROOT}/ani"

TEMP_REPO=""
TEMP_RCFILE=""

usage() {
    cat <<'EOF'
Create a disposable Pijul repo for manually testing `pijul:record-with-intent-tags`.

Usage:
  scripts/pijul-record-with-intent-tags-test-helper

Behavior:
  - Creates a temporary repo with a recorded baseline and pending changes.
  - Opens an interactive shell inside that repo.
  - Prints the exact command to run and the files/hunks worth selecting.
  - Deletes the temporary repo automatically when you exit the shell.

Inside the test shell:
  - Run `record_test` to execute the record-with-tags command against the temp repo.
  - Run `end_test` or `exit` when you are done.
EOF
}

cleanup() {
    local exit_code=$?

    trap - EXIT INT TERM HUP

    if [[ -n "${TEMP_RCFILE}" && -f "${TEMP_RCFILE}" ]]; then
        rm -f "${TEMP_RCFILE}"
    fi

    if [[ -n "${TEMP_REPO}" && -d "${TEMP_REPO}" ]]; then
        rm -rf "${TEMP_REPO}"
        printf '\nCleaned up temporary repo: %s\n' "${TEMP_REPO}"
    fi

    exit "${exit_code}"
}

require_command() {
    local command_name="$1"

    if ! command -v "${command_name}" >/dev/null 2>&1; then
        printf 'Missing required command: %s\n' "${command_name}" >&2
        exit 1
    fi
}

write_initial_files() {
    cat > "${TEMP_REPO}/README.md" <<'EOF'
# Demo repo for ani

This repo exists only for testing `pijul:record-with-intent-tags`.

## Quick notes

- Start with an initial recorded change.
- Add multiple unrecorded hunks afterward.
- Use the helper command to try selecting only part of the work.

## Checklist

1. Run the ani command.
2. Pick a tag or skip it.
3. Enter a message.
4. Select only the README hunks.
EOF

    cat > "${TEMP_REPO}/notes.txt" <<'EOF'
notes
- baseline entry
EOF
}

write_pending_changes() {
    cat > "${TEMP_REPO}/README.md" <<'EOF'
# Demo repo for ani

This repo exists only for testing `pijul:record-with-intent-tags`.
Try recording only the README hunks first.

## Quick notes

- Start with an initial recorded change.
- Add multiple unrecorded hunks afterward.
- Use the helper command to try selecting only part of the work.

## Checklist

1. Run the ani command.
2. Pick a tag or skip it.
3. Enter a message.
4. Select only the README hunks.
5. Confirm that `notes.txt` is still pending afterward.

## Expected result

If you only record the README hunks, `pijul diff --short` should still show `M notes.txt`.
EOF

    cat > "${TEMP_REPO}/notes.txt" <<'EOF'
notes
- baseline entry
- leave this file unselected during the first test run
EOF
}

create_temp_repo() {
    TEMP_REPO="$(mktemp -d "${TMPDIR:-/tmp}/ani-pijul-record-test.XXXXXX")"

    pijul init "${TEMP_REPO}" >/dev/null

    write_initial_files

    (
        cd "${TEMP_REPO}"
        pijul add README.md notes.txt >/dev/null
        EDITOR=true pijul record -m 'feat(test-helper): seed demo repo' >/dev/null
    )

    write_pending_changes
}

create_rcfile() {
    TEMP_RCFILE="$(mktemp "${TMPDIR:-/tmp}/ani-pijul-record-shell.XXXXXX")"

    cat > "${TEMP_RCFILE}" <<'EOF'
record_test() {
    "${ANI_RECORD_TEST_ANI}" pijul:record-with-intent-tags --repository "${PWD}" "$@"
}

end_test() {
    exit
}

export PS1='(ani-record-test) \w $ '
EOF
}

print_instructions() {
    cat <<EOF
Temporary repo ready:
  ${TEMP_REPO}

Changed files waiting to be recorded:
  - README.md (multiple hunks)
  - notes.txt (leave this unselected on your first run)

Inside the shell, run:
  record_test

Exact command:
  ${ANI_BIN} pijul:record-with-intent-tags --repository "${TEMP_REPO}"

Suggested manual check:
  1. Run \`record_test\`.
  2. Enter any message you want.
  3. In the hunk picker, select only the README.md hunks.
  4. After it records, run: pijul diff --short
  5. You should still see: M notes.txt

When you are done, type \`end_test\` or just \`exit\`.
The helper will remove the temp repo automatically.
EOF
}

open_test_shell() {
    (
        cd "${TEMP_REPO}"
        export ANI_RECORD_TEST_ANI="${ANI_BIN}"
        export ANI_RECORD_TEST_REPO="${TEMP_REPO}"
        bash --noprofile --rcfile "${TEMP_RCFILE}" -i
    )
}

main() {
    case "${1-}" in
        -h|--help)
            usage
            exit 0
            ;;
        "")
            ;;
        *)
            printf 'Unexpected argument: %s\n\n' "${1}" >&2
            usage >&2
            exit 1
            ;;
    esac

    require_command pijul
    require_command bash

    if [[ ! -x "${ANI_BIN}" ]]; then
        printf 'Expected ani executable at %s\n' "${ANI_BIN}" >&2
        exit 1
    fi

    trap cleanup EXIT INT TERM HUP

    create_temp_repo
    create_rcfile
    print_instructions
    open_test_shell
}

main "$@"