#!/usr/bin/env bash
#
# Bump the crate version on a dedicated branch and open a release PR.
#
# This is the local, human-driven counterpart to an automated post-release bump:
# it runs scripts/bump-version.sh, commits the result on a `chore/bump-vX.Y.Z`
# branch, pushes it, and opens a PR with `gh` so the change flows through CI and
# the merge queue (main is protected — no direct pushes).
#
# Usage:
#   scripts/bump-version-pr.sh [patch|minor|major|X.Y.Z]
#
# Requirements: a clean working tree, the GitHub CLI (`gh`) authenticated, and a
# remote named `origin`.

set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"

log() { echo "$@" >&2; }
die() {
  log "error: $*"
  exit 1
}

command -v gh >/dev/null 2>&1 || die "the GitHub CLI (gh) is required"
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || die "not a git repository"

# Refuse to run on a dirty tree so the bump PR contains only the version change.
if [ -n "$(git status --porcelain)" ]; then
  die "working tree is not clean — commit or stash changes first"
fi

# The bump PR must target the protected default branch so it flows through CI and
# the merge queue. Default to `main` (overridable via BASE=) and require that we
# are on it, so the bump is taken off — and the PR targets — the intended base.
base_branch="${BASE:-main}"
current_branch="$(git rev-parse --abbrev-ref HEAD)"
[ "$current_branch" != "HEAD" ] || die "detached HEAD — check out $base_branch first"
if [ "$current_branch" != "$base_branch" ]; then
  die "must be run from '$base_branch' (currently on '$current_branch'); check it out or set BASE=<branch>"
fi

# Perform the actual version bump; capture the resulting version.
new="$(CARGO="${CARGO:-cargo}" "$ROOT/scripts/bump-version.sh" "${1:-patch}")"
[ -n "$new" ] || die "bump-version.sh did not report a new version"

branch="chore/bump-v$new"
log "creating branch $branch off $base_branch"
git checkout -b "$branch"

git add Cargo.toml Cargo.lock

# Build the commit message and hard-wrap the body at 72 columns before handing it
# to git. commitlint (@commitlint/config-conventional) enforces body-max-line-length
# of 100 on every PR, so wrapping here keeps generated bump commits under the limit
# categorically — no single body line can exceed the fold width.
commit_subject="chore(release): bump version to $new"
commit_body="Prepare the next development version. The crate version in Cargo.toml is the single source of truth for crates.io, the npm packages, and the GitHub Release."
{
  printf '%s\n\n' "$commit_subject"
  printf '%s\n' "$commit_body" | fold -s -w 72 | sed 's/[[:space:]]*$//'
} | git commit -q -F -

log "pushing $branch to origin"
git push -u origin "$branch"

log "opening PR"
gh pr create \
  --base "$base_branch" \
  --head "$branch" \
  --title "chore(release): bump version to $new" \
  --body "Bumps the crate version to \`$new\` (single source of truth in \`Cargo.toml\`; npm package versions and the crates.io/GitHub Release all derive from it).

Generated by \`make bump-pr\`."

log "done: PR opened for $branch"
