#!/bin/bash
# Create a GitHub pull request using gh CLI.
#
# Usage:
#   create-pr.sh <title> --body-file <path> [--base <branch>]
#   create-pr.sh <title> --body "<markdown>" [--base <branch>]
#
# The head branch is auto-detected by gh from the current git branch and is
# never an argument. The base defaults to main. Prefer --body-file for any
# body longer than a few lines: the file goes to gh untouched, so shell
# quoting cannot mangle the markdown.
#
# The body is mandatory. Before submission it must contain the sections
# docs/GITHUB_WORKFLOW_SPEC.md requires (checked here); after submission the
# PR is read back from GitHub and compared to what was submitted, and the
# script exits nonzero on any mismatch. There is no --fill fallback: a body
# this script did not receive explicitly must never appear on a PR.
#
# History: this script once took the body as a bare second positional argument
# and ignored anything past the third. A caller that inserted the branch name
# as a second argument published the branch name as the PR body while the
# composed body was dropped, and the script reported success. Strict flags,
# rejection of unknown arguments, and read-back verification exist so that
# call shape fails loudly instead.

set -e

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=lib.sh
source "$SCRIPT_DIR/lib.sh"

usage() {
    echo "Usage: $0 <title> (--body \"<markdown>\" | --body-file <path>) [--base <branch>]" >&2
}

TITLE="$1"
if [ -z "$TITLE" ]; then
    echo "Error: missing PR title" >&2
    usage
    exit 1
fi
case "$TITLE" in
    --*)
        echo "Error: the first argument must be the PR title, got a flag: $TITLE" >&2
        usage
        exit 1
        ;;
esac
shift

if ! command -v gh &> /dev/null; then
    echo "Error: GitHub CLI (gh) is not installed" >&2
    echo "Install: https://cli.github.com/" >&2
    exit 1
fi

BODY=""
BODY_FILE=""
BASE="main"

while [ -n "$1" ]; do
    case "$1" in
        --body)
            BODY="$2"
            if [ -z "$BODY" ]; then
                echo "Error: --body requires a non-empty value" >&2
                exit 1
            fi
            shift 2
            ;;
        --body-file)
            BODY_FILE="$2"
            if [ -z "$BODY_FILE" ] || [ ! -f "$BODY_FILE" ]; then
                echo "Error: --body-file requires a path to an existing file (got: ${BODY_FILE:-<empty>})" >&2
                exit 1
            fi
            shift 2
            ;;
        --base)
            BASE="$2"
            if [ -z "$BASE" ]; then
                echo "Error: --base requires a non-empty value" >&2
                exit 1
            fi
            shift 2
            ;;
        *)
            echo "Error: unknown argument: $1" >&2
            echo "The body is passed with --body or --body-file, never positionally." >&2
            echo "The head branch is never an argument; gh detects it from the current branch." >&2
            usage
            exit 1
            ;;
    esac
done

if [ -n "$BODY" ] && [ -n "$BODY_FILE" ]; then
    echo "Error: --body and --body-file are mutually exclusive" >&2
    exit 1
fi

if [ -z "$BODY" ] && [ -z "$BODY_FILE" ]; then
    echo "Error: a PR body is required (--body or --body-file); there is no --fill fallback" >&2
    usage
    exit 1
fi

if [ -n "$BODY_FILE" ]; then
    BODY="$(cat "$BODY_FILE")"
fi

require_pr_body_sections "$BODY"

if [ -n "$BODY_FILE" ]; then
    PR_URL="$(gh pr create --title "$TITLE" --base "$BASE" --body-file "$BODY_FILE")"
else
    PR_URL="$(gh pr create --title "$TITLE" --base "$BASE" --body "$BODY")"
fi

verify_pr_content "$PR_URL" "$TITLE" "$BODY"

echo "$PR_URL"
