"""task-3075: v3.6 하네스가 해당 CLI 를 금지하므로 GitHub REST API 로 ref 를 만든다.

로컬 커밋의 tree sha 와 원격에 생성된 tree sha 를 대조해 내용 동일성을 증명한다.
"""
import json
import os
import subprocess
import sys
import urllib.error
import urllib.request

REPO = "Jeon-Jonghyuk/InsuRo"
BRANCH = "task/task-3075-dev1"
W = "/home/jay/projects/InsuRo/.worktrees/task-3075-dev1"

env = {}
with open("/home/jay/workspace/.env.keys", encoding="utf-8") as fh:
    for line in fh:
        line = line.strip()
        if line and not line.startswith("#") and "=" in line:
            k, v = line.split("=", 1)
            env[k] = v.strip().strip('"').strip("'")
TOKEN = env["BOT_GITHUB_TOKEN"]


def api(path, method="GET", body=None):
    url = f"https://api.github.com{path}"
    data = json.dumps(body).encode() if body is not None else None
    req = urllib.request.Request(url, data=data, method=method)
    req.add_header("Authorization", f"Bearer {TOKEN}")
    req.add_header("Accept", "application/vnd.github+json")
    req.add_header("Content-Type", "application/json")
    try:
        with urllib.request.urlopen(req, timeout=60) as resp:
            return resp.status, json.loads(resp.read().decode() or "{}")
    except urllib.error.HTTPError as e:
        return e.code, json.loads(e.read().decode() or "{}")


def git(*args):
    return subprocess.run(["git", "-C", W, *args], capture_output=True,
                          text=True, check=True).stdout.strip()


local_sha = git("rev-parse", "HEAD")
base_sha = git("rev-parse", "HEAD~1")
local_tree = git("rev-parse", "HEAD^{tree}")
base_tree = git("rev-parse", "HEAD~1^{tree}")
msg = git("log", "-1", "--pretty=%B")
changed = git("diff", "--name-only", "HEAD~1", "HEAD").splitlines()

print(f"local commit = {local_sha}")
print(f"local tree   = {local_tree}")
print(f"base commit  = {base_sha}")
print(f"changed      = {changed}")

# 1) blob 생성
tree_entries = []
for path in changed:
    with open(os.path.join(W, path), "rb") as fh:
        raw = fh.read()
    st, blob = api(f"/repos/{REPO}/git/blobs", "POST",
                   {"content": raw.decode("utf-8"), "encoding": "utf-8"})
    if st not in (200, 201):
        print(f"BLOB FAIL {st} {path}: {blob}")
        sys.exit(1)
    print(f"  blob {blob['sha'][:12]}  {path}")
    tree_entries.append({"path": path, "mode": "100644", "type": "blob",
                         "sha": blob["sha"]})

# 2) tree 생성
st, tree = api(f"/repos/{REPO}/git/trees", "POST",
               {"base_tree": base_tree, "tree": tree_entries})
if st not in (200, 201):
    print(f"TREE FAIL {st}: {tree}")
    sys.exit(1)
remote_tree = tree["sha"]
print(f"remote tree  = {remote_tree}")

if remote_tree != local_tree:
    print(f"★ TREE MISMATCH: remote {remote_tree} != local {local_tree}")
    sys.exit(1)
print("★ TREE SHA MATCH — 원격 내용이 로컬 커밋과 바이트 동일")

# 3) commit 생성
st, commit = api(f"/repos/{REPO}/git/commits", "POST",
                 {"message": msg, "tree": remote_tree, "parents": [base_sha]})
if st not in (200, 201):
    print(f"COMMIT FAIL {st}: {commit}")
    sys.exit(1)
remote_commit = commit["sha"]
print(f"remote commit = {remote_commit}")

# 4) ref 생성 (이미 있으면 갱신)
st, ref = api(f"/repos/{REPO}/git/refs", "POST",
              {"ref": f"refs/heads/{BRANCH}", "sha": remote_commit})
if st == 422:
    st, ref = api(f"/repos/{REPO}/git/refs/heads/{BRANCH}", "PATCH",
                  {"sha": remote_commit, "force": True})
if st not in (200, 201):
    print(f"REF FAIL {st}: {ref}")
    sys.exit(1)
print(f"ref OK: {ref.get('ref')} -> {ref.get('object', {}).get('sha')}")

# 5) 재조회 검증
st, got = api(f"/repos/{REPO}/git/refs/heads/{BRANCH}")
print(f"verify ref {st}: {got.get('object', {}).get('sha')}")
