#!/usr/bin/env python
"""同步 Qoder Repo Wiki → 平台 PG wiki 表。

Qoder 自动为代码仓库生成 Repo Wiki（750+篇业务文档），存在：
  data/code/{repo}/.qoder/repowiki/knowledge/zh/**/*.md

本脚本读这些 md → UPSERT 到 PG wiki 表（repo + keyword + title + description）。
这样知识层的 wiki 搜索(graphrag_ask/rag_search)能命中 Qoder 自动生成的高质量文档。

用法：
    python sync_repowiki.py                          # 同步全部仓库
    python sync_repowiki.py --repo fywl-ics          # 只同步指定仓库
    python sync_repowiki.py --dry-run                # 只统计不写
"""
import os
import sys
import glob

_THIS_DIR = os.path.dirname(os.path.abspath(__file__))
_up1 = os.path.dirname(_THIS_DIR)
_up2 = os.path.dirname(_up1)
SCRIPTS_DIR = os.path.dirname(_up2)
REPO_ROOT = os.path.dirname(SCRIPTS_DIR)
CODE_ROOT = os.path.join(REPO_ROOT, "data", "code")

PG = dict(host="127.0.0.1", port=5432, user="wlinkj", password="changeme", dbname="wlinkj")


def scan_repowiki(repo):
    """扫描某仓库的 Repo Wiki，返回 [{path, title, content, dir_path}]。"""
    wiki_base = os.path.join(CODE_ROOT, repo, ".qoder", "repowiki")
    if not os.path.isdir(wiki_base):
        return []
    results = []
    for md_path in glob.glob(os.path.join(wiki_base, "**", "*.md"), recursive=True):
        try:
            with open(md_path, encoding="utf-8") as f:
                content = f.read()
            # 标题：md 文件名或第一行 #
            title = os.path.splitext(os.path.basename(md_path))[0]
            for line in content.split("\n")[:5]:
                if line.strip().startswith("#"):
                    title = line.strip().lstrip("#").strip()
                    break
            # keyword：从目录路径提取业务模块名
            rel = os.path.relpath(md_path, wiki_base)
            parts = rel.replace("\\", "/").split("/")
            keyword = parts[-2] if len(parts) >= 2 else title
            results.append({
                "path": md_path,
                "rel_path": rel,
                "title": title,
                "keyword": keyword,
                "content": content[:2000],  # 取前2000字
            })
        except Exception:
            continue
    return results


def sync_to_pg(wiki_items, repo):
    """UPSERT 到 PG wiki 表。"""
    import psycopg2
    from psycopg2.extras import execute_values

    conn = psycopg2.connect(**PG)
    conn.autocommit = True
    cur = conn.cursor()

    # ★ 不删旧数据（原 wiki 表有业务文档），只删 repowiki 来源的记录
    # 用 md_path 前缀 'repowiki:' 标识（避免路径分隔符差异）
    cur.execute("DELETE FROM wiki WHERE project = %s AND md_path LIKE 'repowiki:%%'", (repo,))

    rows = [(w["keyword"], repo, w["title"], "repowiki:" + w["rel_path"], w["content"][:500])
            for w in wiki_items]
    if rows:
        execute_values(
            cur,
            "INSERT INTO wiki(keyword, project, title, md_path, description) VALUES %s",
            rows,
        )

    print(f"[{repo}] 同步 {len(rows)} 篇 Wiki 到 PG")
    conn.close()


def main():
    import argparse
    parser = argparse.ArgumentParser(description="同步 Qoder Repo Wiki → PG")
    parser.add_argument("--repo", help="指定仓库名")
    parser.add_argument("--dry-run", action="store_true", help="只统计不写")
    args = parser.parse_args()

    repos = [args.repo] if args.repo else ["fywl-ui", "fywl-ics", "Carmg-H5"]
    total = 0
    for repo in repos:
        items = scan_repowiki(repo)
        print(f"  {repo}: 扫到 {len(items)} 篇 Repo Wiki")
        if items:
            for it in items[:3]:
                print(f"    [{it['keyword']}] {it['title']}")
            if not args.dry_run:
                sync_to_pg(items, repo)
            total += len(items)
    print(f"\n总计: {total} 篇 Wiki{'（dry-run 未写入）' if args.dry_run else ' 已同步到 PG'}")


if __name__ == "__main__":
    main()
