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

Parameterized over title/body 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_issue.py --title "Bug: blank PDF" --body "Blank on Safari"
    create_issue.py --remote prgs --title "Add tests" --body-file desc.md
    create_issue.py --host gitea.example.com --org Foo --repo Bar --title "..."
"""
import os
import sys
import argparse

# 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,
    api_request, repo_api_url,
)
import issue_workflow_labels


def main(argv=None):
    parser = argparse.ArgumentParser(description="Create a Gitea issue.")
    add_remote_args(parser)
    parser.add_argument("--title", required=True, help="Issue title.")
    parser.add_argument("--body", default="", help="Issue body text.")
    parser.add_argument("--body-file",
                        help="Read issue body from this file ('-' for stdin).")
    parser.add_argument("--label", action="append", default=[],
                        help="Existing label name to apply; may be repeated.")
    parser.add_argument("--type-label",
                        help="Issue type, e.g. feature or type:feature.")
    parser.add_argument("--status-label",
                        help="Initial status, e.g. ready or status:ready.")
    parser.add_argument("--discussion", action="store_true",
                        help="Apply type:discussion.")
    parser.add_argument("--require-workflow-labels", action="store_true",
                        help="Fail unless one type:* and one status:* label are supplied.")
    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()

    requested_labels = issue_workflow_labels.labels_for_new_issue(
        issue_type=args.type_label,
        initial_status=args.status_label,
        extra_labels=args.label,
        discussion=args.discussion,
    )
    label_assessment = issue_workflow_labels.assess_issue_labels(
        requested_labels,
        discussion=args.discussion,
    )
    if args.require_workflow_labels and not label_assessment["valid"]:
        print(
            "Workflow label validation failed: "
            + "; ".join(label_assessment["errors"]),
            file=sys.stderr,
        )
        return 1

    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

    import base64
    auth = f"Basic {base64.b64encode(f'{user}:{password}'.encode()).decode()}"
    base = repo_api_url(host, org, repo)
    url = f"{base}/issues"

    try:
        label_ids = []
        if requested_labels:
            existing = api_request("GET", f"{base}/labels", auth)
            by_name = {lb["name"]: lb["id"] for lb in existing}
            missing = [name for name in requested_labels if name not in by_name]
            if missing:
                print(f"Missing labels: {missing}", file=sys.stderr)
                return 1
            label_ids = [by_name[name] for name in requested_labels]
        data = api_request("POST", url, auth, {"title": args.title, "body": body})
        if label_ids:
            api_request(
                "PUT",
                f"{base}/issues/{data.get('number')}/labels",
                auth,
                {"labels": label_ids},
            )
        print(f"Issue #{data.get('number')}: {data.get('html_url')}")
        if not label_assessment["valid"]:
            print(
                "Workflow label recommendation: "
                + "; ".join(label_assessment["errors"]),
                file=sys.stderr,
            )
        return 0
    except RuntimeError as e:
        print(f"Error: {e}", file=sys.stderr)
        return 1


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