#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""补生成缺失题的相似问法，合并进 相似问法-全集.json"""
import json, os, subprocess, re, uuid, glob

BASE = "/home/zyw/Downloads/dl-hub/01-AI课程设计项目/知识库问答库"
ALL = json.load(open(os.path.join(BASE,"题目全集.json"), encoding='utf-8'))
S = os.path.expanduser("~/.dsh/skills/grok-run/scripts/grok-run.sh")

def load_merged():
    m = {}
    for f in glob.glob(os.path.join(BASE,"相似问法分片","sim-*.json")):
        for k,v in json.load(open(f,encoding='utf-8')).items():
            if str(k) not in m: m[str(k)] = v
    # 若已有全集文件，叠加
    p = os.path.join(BASE,"相似问法-全集.json")
    if os.path.exists(p):
        for k,v in json.load(open(p,encoding='utf-8')).items():
            if str(k) not in m: m[str(k)] = v
    return m

def gen_ones(nids):
    items = [ALL[i] for i in nids]
    for j, it in enumerate(items): it["_i"] = nids[j]
    def qc(q):
        x = re.sub(r'```python.*?```', '【代码见原题】', q, flags=re.S)
        return x[:100] + ("…" if len(x)>100 else "")
    lines = [f'{it["_i"]}|{qc(it["q"])}' for it in items]
    prompt = ("你是AI课程问答库编辑。下面每行是「题目序号|标准问题」，请为每一题生成 3 条相似问法"
              "（等价问法：换措辞/换句式/口语化均可，不能改变答案语义，不能变反义，不能把单选变多选）。"
              "只输出一个 JSON 对象：键为题目序号，值为长度 3 的字符串数组，每条 ≤80 字；"
              "必须覆盖全部给出的序号。除 JSON 外不要任何内容。\n\n" + "\n".join(lines))
    tmp = f"/tmp/simfix-{uuid.uuid4().hex[:8]}.json"
    for attempt in range(3):
        r = subprocess.run(["bash", S, prompt, "--out", tmp, "--max-turns", "40"],
                           capture_output=True, text=True, timeout=900)
        txt = ""
        for c in (tmp, tmp+".final-text.txt"):
            try:
                if os.path.exists(c) and open(c,encoding='utf-8').read().strip():
                    txt = open(c,encoding='utf-8').read(); break
            except: pass
        data = {}
        for m in re.finditer(r'"(\d+)"\s*:\s*\[(.*?)\]', txt, re.S):
            vals = re.findall(r'"((?:[^"\\]|\\.)*)"', m.group(2))
            if len(vals) >= 2:
                data[m.group(1)] = [v.replace('\\"','"').replace('\\\\','\\') for v in vals]
        miss = [str(n) for n in nids if str(n) not in data]
        if not miss:
            return data
        prompt += "\n注意：上一次缺少序号 " + ",".join(miss[:12]) + "，请补齐后再输出完整JSON。"
    return data

def main():
    merged = load_merged()
    missing = [i for i in range(1299) if str(i) not in merged]
    print("当前缺失:", len(missing), missing[:20], flush=True)
    fixed = {}
    for i in range(0, len(missing), 8):
        chunk = missing[i:i+8]
        d = gen_ones(chunk)
        got = sum(1 for n in chunk if str(n) in d)
        for n in chunk:
            if str(n) in d: fixed[str(n)] = d[str(n)]
        print(f"补批 {i//8+1}/{(len(missing)+7)//8}: 得 {got}/{len(chunk)}", flush=True)
    for k,v in fixed.items():
        merged[str(k)] = v
    still = [i for i in range(1299) if str(i) not in merged]
    print("补后仍缺:", len(still), still[:30], flush=True)
    json.dump({k: merged[k] for k in sorted(merged, key=int)},
              open(os.path.join(BASE,"相似问法-全集.json"),"w",encoding='utf-8'),
              ensure_ascii=False, indent=1)
    print("已写 相似问法-全集.json, 键数:", len(merged), flush=True)
    # 对仍缺的：尝试第2轮（单题）
    if still:
        for nid in still[:30]:
            d = gen_ones([nid])
            if str(nid) in d:
                merged[str(nid)] = d[str(nid)]
        still2 = [i for i in range(1299) if str(i) not in merged]
        print("最终仍缺:", len(still2), still2, flush=True)
        json.dump({k: merged[k] for k in sorted(merged, key=int)},
                  open(os.path.join(BASE,"相似问法-全集.json"),"w",encoding='utf-8'),
                  ensure_ascii=False, indent=1)
main()
