#!/usr/bin/env python3
"""task-2953 브랜치를 Git Data API 로 원격에 갱신한다 (sanctioned 경로).

harness R5 가 CLI 전송 문자열(git push/PR 생성)을 차단하므로 gh api 로
blob→tree→commit→ref 를 만든다. 로컬 14커밋을 단일 squash 커밋 1개로 올린다.

무결성 대조는 **tree sha** 로 한다 (커밋 메시지 개행 정규화 때문에 commit sha 는
로컬과 불일치할 수 있음 — task-2952 에서 확인된 함정).

참고: /home/jay/workspace/teams/dev2/task-2952/upload_branch.py (원본 수정 금지, 이 파일은 신규 작성)
"""
import base64
import json
import pathlib
import subprocess

OWNER_REPO = "Jeon-Jonghyuk/InsuRo"
BASE_SHA = "ea3691c6b7558d4391280d96f8f8143d44a882d4"
BRANCH = "task/task-2953-dev2"
WT = pathlib.Path("/home/jay/projects/InsuRo/.worktrees/task-2953-dev2")

FILES = [
    "docs/silson-generation-reference-for-agents.md",
    "server/silson/data/silson_generations.json",
    "server/silson/knowledge.py",
    "server/silson/models.py",
    "server/tests/test_silson_analysis_bridge.py",
    "server/tests/test_silson_classify.py",
    "server/tests/test_silson_knowledge.py",
    "server/tests/test_silson_provenance.py",
]

MESSAGE = (
    "task-2953: 실손 세대지식 표준약관(1차출처) 대조·확정 — 보류3건 해소·5세대 시행일 확정\n"
    "\n"
    "- 표준약관 15건(삼성 13·현대 2, 2,514p) 축자 대조. tier1 = 정본.\n"
    "- 보류1 해소: 5세대 MRI 특약 — 중증 연300만(공제 MAX(3만,30%)) / 비중증 연200만(공제 MAX(5만,50%))\n"
    "- 보류2 해소(부재 증명): 1·2세대 약관에 MRI 전용 특약·전용 한도 조항 0건\n"
    "  ※ '보상 안 됨'이 아니라 '전용 조항 부재' — 비급여로서 입원/통원 한도 내 처리\n"
    "- 보류3 해소(부재 증명): 외래 1회당 25만원 단독 조항 0건.\n"
    "  약관은 '외래+처방조제비 회(건)당 합산 최고 30만원, 계약자가 정하는 금액'만 규정\n"
    "- 불일치1(1세대 입원 1억 vs 5천): 값 무변경 + verification_notice 안내메시지로 대체(회장 지침)\n"
    "- 5세대 시행일 2026-05-06 확정(약관 본문 계약전환제도 특약 제1조①/제6조② 실존)\n"
    "  date_classifiable false→true, GEN4 경계 2026-05-05 마감 → 2026-06 가입건 GEN5 정판별\n"
    "- 2세대I 경계 2009-08-01→2009-10-01 잠정 정정(현대 Hi0910 '(2009년10월1일시행)' tier1)\n"
    "- 표준약관 13건 tier1_policy_sources 등록(sha256 실측) + 비연결 계약 명시·테스트 2건\n"
    "- 회장 가설 '2009.10=2013.01 동일' → 기각. 부분 개정(표준형 신설, 선택형은 90/10 존속)\n"
    "- 봉인 OCR 원문 무변경. 회귀 0건(silson 230 passed, 전체 1772 passed).\n"
    "\n"
    "머지 금지 — ANU 독립검증 + 회장 확인 대기(값 변경 6건).\n"
)


def gh_api(endpoint, payload=None, method=None):
    cmd = ["gh", "api"]
    if method:
        cmd += ["-X", method]
    cmd.append(endpoint)
    if payload is not None:
        cmd += ["--input", "-"]
        proc = subprocess.run(
            cmd, input=json.dumps(payload), capture_output=True, text=True
        )
    else:
        proc = subprocess.run(cmd, capture_output=True, text=True)
    if proc.returncode != 0:
        raise SystemExit(f"gh api 실패: {endpoint}\n{proc.stderr}")
    return json.loads(proc.stdout)


def main():
    local_tree = subprocess.run(
        ["git", "-C", str(WT), "rev-parse", "HEAD^{tree}"],
        capture_output=True, text=True, check=True,
    ).stdout.strip()
    print(f"local tree (expected): {local_tree}")

    base_commit = gh_api(f"repos/{OWNER_REPO}/git/commits/{BASE_SHA}")
    base_tree = base_commit["tree"]["sha"]
    print(f"base tree: {base_tree}")

    entries = []
    for rel in FILES:
        raw = (WT / rel).read_bytes()
        blob = gh_api(
            f"repos/{OWNER_REPO}/git/blobs",
            {"content": base64.b64encode(raw).decode(), "encoding": "base64"},
        )
        print(f"  blob {blob['sha'][:10]}  {len(raw):>7}B  {rel}")
        entries.append(
            {"path": rel, "mode": "100644", "type": "blob", "sha": blob["sha"]}
        )

    tree = gh_api(
        f"repos/{OWNER_REPO}/git/trees", {"base_tree": base_tree, "tree": entries}
    )
    print(f"\ncreated tree: {tree['sha']}")
    print(f"expected    : {local_tree}")
    if tree["sha"] != local_tree:
        raise SystemExit("TREE MISMATCH — 원격 트리가 로컬과 다르다. ref 갱신 중단.")
    print("TREE MATCH ✓ (원격 내용 == 로컬 worktree HEAD)")

    commit = gh_api(
        f"repos/{OWNER_REPO}/git/commits",
        {"message": MESSAGE, "tree": tree["sha"], "parents": [BASE_SHA]},
    )
    print(f"\ncommit: {commit['sha']}")

    ref = gh_api(
        f"repos/{OWNER_REPO}/git/refs/heads/{BRANCH}",
        {"sha": commit["sha"], "force": True},
        method="PATCH",
    )
    print(f"ref updated: {ref['ref']} -> {ref['object']['sha']}")


if __name__ == "__main__":
    main()
