#!/usr/bin/env python3
import json, os, subprocess, sys, tempfile, time, urllib.request
from pathlib import Path

BASE = os.environ.get('GITEA_API_BASE', 'https://forge.alexanderwhitestone.com/api/v1')
REPO = sys.argv[1]
ISSUE_NUM = int(sys.argv[2])
ISSUE_TITLE = sys.argv[3]
OWNER, NAME = REPO.split('/')
BRANCH = f'claw-code/issue-{ISSUE_NUM}'
WORKTREE = Path.home() / 'worktrees' / f'claw-code-{ISSUE_NUM}'
CLAW_ROOT = Path.home() / 'code-claw' / 'rust'
CLAW_BIN = CLAW_ROOT / 'target' / 'debug' / 'claw'
CLAW_HOME = Path.home() / '.claw-qwen36-gitea'
OPENROUTER_KEY = (Path.home() / '.timmy' / 'openrouter_key').read_text().strip()
GITEA_TOKEN = (Path.home() / '.config' / 'gitea' / 'claw-code-token').read_text().strip()

headers = {'Authorization': f'token {GITEA_TOKEN}', 'Content-Type': 'application/json', 'Accept': 'application/json'}

def api(method, path, data=None):
    req = urllib.request.Request(f"{BASE}{path}", headers=headers, method=method)
    if data is not None:
        body = json.dumps(data).encode()
        req.data = body
    with urllib.request.urlopen(req, timeout=30) as resp:
        raw = resp.read().decode()
        return json.loads(raw) if raw else {}

def comment(body):
    return api('POST', f'/repos/{OWNER}/{NAME}/issues/{ISSUE_NUM}/comments', {'body': body})

def issue_labels():
    return api('GET', f'/repos/{OWNER}/{NAME}/labels?limit=100')

def issue_data():
    return api('GET', f'/repos/{OWNER}/{NAME}/issues/{ISSUE_NUM}')

def comments():
    return api('GET', f'/repos/{OWNER}/{NAME}/issues/{ISSUE_NUM}/comments')

def find_exact_open_pr(branch_name):
    prs = api('GET', f'/repos/{OWNER}/{NAME}/pulls?state=open&limit=100')
    for pr in prs:
        head = (pr.get('head') or {}).get('ref')
        if head == branch_name:
            return pr
    return None

def label_id(name):
    for l in issue_labels():
        if l['name'] == name:
            return l['id']
    return None

def add_label(name):
    lid = label_id(name)
    if lid:
        api('POST', f'/repos/{OWNER}/{NAME}/issues/{ISSUE_NUM}/labels', {'labels': [lid]})

def remove_label(name):
    lid = label_id(name)
    if lid:
        try:
            api('DELETE', f'/repos/{OWNER}/{NAME}/issues/{ISSUE_NUM}/labels/{lid}')
        except Exception:
            pass

def run(cmd, cwd=None, env=None, timeout=900, check=True):
    p = subprocess.run(cmd, cwd=cwd, env=env, text=True, capture_output=True, timeout=timeout)
    if check and p.returncode != 0:
        raise RuntimeError(f'cmd failed: {cmd}\nstdout:\n{p.stdout}\nstderr:\n{p.stderr}')
    return p

# fetch issue body/comments
issue = issue_data()
body = issue.get('body') or ''
cmts = comments()
comment_text = '\n\n'.join([c.get('body','') for c in cmts[-8:]])[:6000]

# clone target repo
if WORKTREE.exists():
    subprocess.run(['rm','-rf',str(WORKTREE)])
clone_url = f'https://claw-code:{GITEA_TOKEN}@forge.alexanderwhitestone.com/{OWNER}/{NAME}.git'
run(['git','clone','--depth','1','-b','main',clone_url,str(WORKTREE)], cwd=str(Path.home()))
run(['git','checkout','-b',BRANCH], cwd=str(WORKTREE))
run(['git','config','user.name','claw-code'], cwd=str(WORKTREE))
run(['git','config','user.email','claw-code@timmy.local'], cwd=str(WORKTREE))

prompt = f'''You are Code Claw running as the Gitea user claw-code.

Repository: {REPO}
Issue: #{ISSUE_NUM} — {ISSUE_TITLE}
Branch: {BRANCH}

Read the issue and recent comments, then implement the smallest correct change.
You are in a git repo checkout already.

Issue body:
{body}

Recent comments:
{comment_text}

Rules:
- Make focused code/config/doc changes only if they directly address the issue.
- Prefer the smallest proof-oriented fix.
- Run relevant verification commands if obvious.
- Do NOT create PRs yourself; the outer worker handles commit/push/PR.
- If the task is too large or not code-fit, leave the tree unchanged.
'''

env = os.environ.copy()
env['CLAW_FORCE_OPENAI_COMPAT'] = '1'
env['OPENAI_API_KEY'] = OPENROUTER_KEY
# Anthropic-compatible path via OpenRouter works better with current local patch
env['ANTHROPIC_API_KEY'] = OPENROUTER_KEY
env['ANTHROPIC_BASE_URL'] = 'https://openrouter.ai/api'
env['CLAW_CONFIG_HOME'] = str(CLAW_HOME)

result = run([str(CLAW_BIN), '--model', 'qwen/qwen3.6-plus:free', '--permission-mode', 'workspace-write', '-p', prompt], cwd=str(WORKTREE), env=env, timeout=1200, check=False)

# salvage + commit + push if anything changed
status = run(['git','status','--porcelain'], cwd=str(WORKTREE), check=False)
if status.stdout.strip():
    run(['git','add','-A'], cwd=str(WORKTREE))
    run(['git','commit','-m', f'chore: claw-code progress on #{ISSUE_NUM}\n\nRefs #{ISSUE_NUM}'], cwd=str(WORKTREE), check=False)

ahead = run(['git','log','--oneline','origin/main..HEAD'], cwd=str(WORKTREE), check=False)
has_work = bool(ahead.stdout.strip())
pr_url = ''
if has_work:
    run(['git','push','-u','origin',BRANCH], cwd=str(WORKTREE), check=False)
    pr = find_exact_open_pr(BRANCH)
    if not pr:
        pr = api('POST', f'/repos/{OWNER}/{NAME}/pulls', {
            'title': f'[claw-code] {ISSUE_TITLE} (#{ISSUE_NUM})',
            'head': BRANCH,
            'base': 'main',
            'body': f'Refs #{ISSUE_NUM}\n\nBuilt by Code Claw on OpenRouter qwen/qwen3.6-plus:free.'
        })
    pr_url = pr.get('html_url','')
    add_label('claw-code-done')
    remove_label('assigned-claw-code')
    remove_label('claw-code-in-progress')
    comment(f'✅ Code Claw completed a pass on this issue.\n\nBranch: `{BRANCH}`\nPR: {pr_url or "(created but URL missing)"}\nExit: {result.returncode}')
else:
    remove_label('claw-code-in-progress')
    comment(f'⚠️ Code Claw made no durable code changes on this pass.\n\nExit: {result.returncode}\nThis likely means the issue is too broad, not code-fit, or needs human clarification.')

print(json.dumps({'issue': ISSUE_NUM, 'repo': REPO, 'exit': result.returncode, 'has_work': has_work, 'pr_url': pr_url}))
