#!/usr/bin/env python3
"""Create a Gitea pull request.

Parameterized over title/body/head/base and the target Gitea instance.
Two instances are known out of the box:

    dadeschools -> gitea.dadeschools.net / Contractor / Timesheet
    prgs        -> gitea.prgs.cc        / Scaled-Tech-Consulting / Timesheet

Auth is pulled from the macOS keychain via `git credential fill` for the
chosen host -- no tokens on the command line.

Examples:
    create_pr.py --remote dadeschools \
        --title "Open generated PDF after creation (#7)" \
        --head feat/7-open-pdf-2234ddf5 --base feat/4-5-24-validations \
        --body "Closes #7"

    create_pr.py --remote prgs --title "Fix X" --head fix/x --body-file body.md

    # override any field of a known remote, or point at an arbitrary repo:
    create_pr.py --host gitea.example.com --org Foo --repo Bar \
        --title "..." --head topic
"""
import os
import sys
import json
import base64
import argparse
import urllib.request
import urllib.error

# Auto-execute using the project's local virtual environment Python
PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
venv_python = os.path.join(PROJECT_ROOT, "venv", "bin", "python3")
if os.path.exists(venv_python) and sys.executable != venv_python:
    os.execv(venv_python, [venv_python] + sys.argv)

from gitea_auth import get_credentials, resolve_remote, add_remote_args


def main(argv=None):
    parser = argparse.ArgumentParser(description="Create a Gitea pull request.")
    add_remote_args(parser)
    parser.add_argument("--title", required=True, help="PR title.")
    parser.add_argument("--head", required=True, help="Source branch.")
    parser.add_argument("--base", default="main", help="Target branch (default: main).")
    parser.add_argument("--body", default="", help="PR body text.")
    parser.add_argument("--body-file", help="Read PR body from this file ('-' for stdin).")
    args = parser.parse_args(argv)

    host, org, repo = resolve_remote(args)

    body = args.body
    if args.body_file:
        if args.body_file == "-":
            body = sys.stdin.read()
        else:
            with open(args.body_file, "r", encoding="utf-8") as fh:
                body = fh.read()

    user, password = get_credentials(host)
    if not user or not password:
        print(f"Could not get credentials for {host} "
              f"(no keychain entry? try a manual `git credential fill`).",
              file=sys.stderr)
        return 1

    url = f"https://{host}/api/v1/repos/{org}/{repo}/pulls"
    payload = {"title": args.title, "body": body, "head": args.head, "base": args.base}
    req = urllib.request.Request(
        url, data=json.dumps(payload).encode("utf-8"),
        headers={"Content-Type": "application/json"},
    )
    auth_b64 = base64.b64encode(f"{user}:{password}".encode("utf-8")).decode("utf-8")
    req.add_header("Authorization", f"Basic {auth_b64}")

    try:
        with urllib.request.urlopen(req) as response:
            data = json.load(response)
        print(f"PR #{data.get('number')}: {data.get('html_url')}")
        return 0
    except urllib.error.HTTPError as e:
        print(f"Error {e.code}: {e.read().decode()}", file=sys.stderr)
        return 1


if __name__ == "__main__":
    sys.exit(main())

