#!/usr/bin/env bash
set -euo pipefail

usage() {
  cat <<'EOF'
usage: scripts/worktree-start [--dry-run] [--allow-unlinked] <branch-name> [start-ref]

Create an issue-linked git worktree under branches/<branch-name-with-slashes-replaced>.

Branch names must be traceable to an issue (or a PR, for review branches):
  implementation: (fix|feat|docs|chore)/issue-<number>-<short-description>
  review:         review/pr-<number>-<short-description>
Use --allow-unlinked to bypass the check (discouraged).

Examples:
  scripts/worktree-start fix/issue-123-example
  scripts/worktree-start --dry-run review/pr-456-scope-check prgs/master
EOF
}

dry_run=0
allow_unlinked=0
while [[ "${1:-}" == --* ]]; do
  case "$1" in
    --dry-run) dry_run=1 ;;
    --allow-unlinked) allow_unlinked=1 ;;
    --help) usage; exit 0 ;;
    *) usage >&2; exit 2 ;;
  esac
  shift
done

if [[ $# -lt 1 || $# -gt 2 ]]; then
  usage >&2
  exit 2
fi

branch="$1"
start_ref="${2:-prgs/master}"

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

# Enforce issue-linked, traceable branch names (issue → branch → worktree → PR).
if [[ "$allow_unlinked" -eq 0 ]]; then
  locked_branch=$(python3 -c "
import sys
sys.path.insert(0, '$repo_root')
import issue_lock_store
print(issue_lock_store.resolve_locked_branch_for_session('$branch'))
")
  if [[ -z "$locked_branch" ]]; then
    echo "Error: No session issue lock is bound. Call gitea_lock_issue before branch creation (fail closed)." >&2
    exit 2
  fi
  if [[ "$branch" != "$locked_branch" ]]; then
    echo "Error: Requested branch '$branch' does not match locked branch '$locked_branch' (fail closed)." >&2
    exit 2
  fi

  if [[ "$branch" =~ ^(fix|feat|docs|chore)/issue-[0-9]+-.+ ]] \
     || [[ "$branch" =~ ^review/pr-[0-9]+-.+ ]]; then
    :
  else
    cat >&2 <<EOF
Untraceable branch name: $branch

Implementation branches must be issue-linked:
  (fix|feat|docs|chore)/issue-<number>-<short-description>
Review branches:
  review/pr-<number>-<short-description>

Fix the branch name, or pass --allow-unlinked to override (discouraged).
EOF
    exit 2
  fi
fi

worktree_name="${branch//\//-}"
worktree_path="$repo_root/branches/$worktree_name"

if [[ -e "$worktree_path" ]]; then
  cat >&2 <<EOF
Refusing to reuse existing branch worktree:
  $worktree_path

Inspect it manually. Do not overwrite or clean another issue's branch folder
unless that issue is explicitly assigned and cleanup is part of the task.
EOF
  exit 1
fi

if [[ "$dry_run" -eq 1 ]]; then
  printf 'repo: %s\n' "$repo_root"
  printf 'branch: %s\n' "$branch"
  printf 'start-ref: %s\n' "$start_ref"
  printf 'worktree: %s\n' "$worktree_path"
  printf 'commands:\n'
  printf '  git -C %q fetch prgs --prune\n' "$repo_root"
  printf '  git -C %q worktree add -b %q %q %q\n' \
    "$repo_root" "$branch" "$worktree_path" "$start_ref"
  exit 0
fi

git -C "$repo_root" fetch prgs --prune
git -C "$repo_root" worktree add -b "$branch" "$worktree_path" "$start_ref"
printf '%s\n' "$worktree_path"
