#!/usr/bin/env python3
from __future__ import annotations

import argparse
import json
import os
import sys
import urllib.error
import urllib.request
from pathlib import Path
from typing import Any

ROOT = Path(__file__).resolve().parents[1]
DEFAULT_BASE_URL = "http://kjh2064.synology.me:8418"
DEFAULT_OWNER = "KimJaeHyun"
DEFAULT_REPO = "myfinance"


def _token() -> str:
    # 토큰 우선순위: GITEA_TOKEN_BAIK → GITEA_TOKEN_TAXBAIK → GITEA_TOKEN → GITEA_TOKEN_HOME
    for env_key in ("GITEA_TOKEN_BAIK", "GITEA_TOKEN_TAXBAIK", "GITEA_TOKEN", "GITEA_TOKEN_HOME"):
        val = os.environ.get(env_key, "").strip()
        if val:
            return val
    raise SystemExit("GITEA_TOKEN_BAIK 또는 GITEA_TOKEN_TAXBAIK 환경 변수가 설정되어 있지 않습니다.")


def _request_json(url: str, token: str, method: str = "GET", body: dict[str, Any] | None = None) -> tuple[int, str, Any]:
    data = None
    headers = {
        "Authorization": f"token {token}",
        "Accept": "application/json",
    }
    if body is not None:
        headers["Content-Type"] = "application/json"
        data = json.dumps(body).encode("utf-8")
    req = urllib.request.Request(url, data=data, headers=headers, method=method)
    try:
        with urllib.request.urlopen(req, timeout=30) as resp:
            raw = resp.read().decode("utf-8", errors="replace")
            payload = json.loads(raw) if raw else None
            return resp.status, resp.reason, payload
    except urllib.error.HTTPError as exc:
        raw = exc.read().decode("utf-8", errors="replace")
        try:
            payload = json.loads(raw) if raw else None
        except Exception:
            payload = raw
        return exc.code, exc.reason or "", payload


def _repo_base(args: argparse.Namespace) -> str:
    return f"{args.base_url.rstrip('/')}/api/v1/repos/{args.owner}/{args.repo}"


def main() -> int:
    ap = argparse.ArgumentParser(description="Create and Validate Gitea Pull Requests automatically.")
    ap.add_argument("--base-url", default=DEFAULT_BASE_URL)
    ap.add_argument("--owner", default=DEFAULT_OWNER)
    ap.add_argument("--repo", default=DEFAULT_REPO)
    ap.add_argument("--head", required=True, help="Branch containing changes (e.g., feature/kis-token-db-cache)")
    ap.add_argument("--base-branch", default="main", help="Target branch to merge changes into")
    ap.add_argument("--title", default=None, help="PR Title")
    ap.add_argument("--body", default="Automated PR generated by quant engine client.", help="PR Description")
    args = ap.parse_args()

    token = _token()
    base = _repo_base(args)
    
    title = args.title or f"Merge {args.head} into {args.base_branch}"
    
    evidence: dict[str, Any] = {
        "base_url": args.base_url,
        "owner": args.owner,
        "repo": args.repo,
        "head": args.head,
        "base_branch": args.base_branch,
    }

    # 1. 원격 저장소 접근 가능 여부 테스트 (Basic Auth/Token Check)
    status, reason, repo_payload = _request_json(base, token)
    evidence["repo_check_status"] = status
    if status != 200:
        print(json.dumps({"gate": "FAIL", "evidence": evidence, "error": "Repository inaccessible. Check credentials/token."}, ensure_ascii=False, indent=2))
        return 1

    # 2. 이미 동일한 Head -> Base PR이 열려 있는지 검사
    status, reason, prs_payload = _request_json(f"{base}/pulls?state=open", token)
    if status == 200 and isinstance(prs_payload, list):
        for pr in prs_payload:
            if pr.get("head", {}).get("ref") == args.head and pr.get("base", {}).get("ref") == args.base_branch:
                evidence["pr_exists"] = True
                evidence["pr_url"] = pr.get("html_url")
                print(json.dumps({"gate": "PASS", "message": "PR already exists and is active.", "evidence": evidence}, ensure_ascii=False, indent=2))
                return 0

    # 3. 신규 Pull Request 작성 API 요청
    pr_body = {
        "title": title,
        "body": args.body,
        "head": args.head,
        "base": args.base_branch,
    }
    
    status, reason, pr_payload = _request_json(f"{base}/pulls", token, method="POST", body=pr_body)
    evidence["create_status"] = status
    evidence["create_reason"] = reason
    
    if status == 201:
        evidence["pr_url"] = pr_payload.get("html_url")
        result = {
            "gate": "PASS",
            "message": f"Successfully created Pull Request for branch: {args.head}",
            "evidence": evidence
        }
        print(json.dumps(result, ensure_ascii=False, indent=2))
        return 0
    else:
        # PR 생성 실패 (동일한 브랜치에 변경 사항이 없거나 권한 부족 등)
        print(json.dumps({"gate": "FAIL", "evidence": evidence, "error": pr_payload}, ensure_ascii=False, indent=2))
        return 1


if __name__ == "__main__":
    raise SystemExit(main())
