#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""verify_danzhai_fts.py —— 第 9 步 FTS 验证（两条路都测）

① DB 层 gov_search MATCH（FTS5 trigram，≥3 字中文）—— 带 site_name 进 SQL，不先 LIMIT 再过滤
② HTTP /crawler/?q=<本站独有词>  v2 列表页（中文词走 gov_bigram 离线索引，新数据可能次日 04:25 才进）
③ HTTP /detail?id=<id> 详情页渲染（表格/段落/链接）
④ gov_bigram 里本站行数（0 = 尚未重建，属预期）
"""
import json
import re
import sqlite3
import urllib.parse
import urllib.request

BASE = "http://127.0.0.1:8000"
SITE = "丹寨县人民政府-环境执法监管"
WORD = "丹寨风电钢结构塔筒"     # 本站独有，5 字
CK = "/tmp/ck_danzhai.txt"

db = sqlite3.connect("/root/search.db", timeout=20)
db.execute("PRAGMA busy_timeout=20000")

print("=== ① DB 层 gov_search MATCH ===")
for w in [WORD, "钢结构塔筒", "罚决字"]:
    try:
        rows = list(db.execute(
            "SELECT g.rowid, g.title FROM gov_search g JOIN gov_raw r ON r.id=g.rowid "
            "WHERE gov_search MATCH ? AND r.site_name=? LIMIT 3", (w, SITE)))
        print("  MATCH %-12s → %d 命中 %s" % (w, len(rows), [r[1][:26] for r in rows]))
    except Exception as e:
        print("  MATCH %-12s → ❌ %s" % (w, str(e)[:60]))

print("\n=== ④ gov_bigram 预计算索引状态 ===")
try:
    n = db.execute("SELECT COUNT(*) FROM gov_bigram WHERE rowid IN "
                   "(SELECT id FROM gov_raw WHERE site_name=?)", (SITE,)).fetchone()[0]
    print("  本站行在 gov_bigram 中:", n, "（0 = 尚未重建，属预期，次日 04:25 增量重建）")
except Exception as e:
    print("  ❌", str(e)[:80])

print("\n=== ③ 登录并测 HTTP ===")
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor())
try:
    req = urllib.request.Request(BASE + "/login", data=b"username=admin",
                                 headers={"Content-Type": "application/x-www-form-urlencoded"})
    r = opener.open(req, timeout=20)
    print("  POST /login → HTTP", r.getcode())
except Exception as e:
    print("  ❌ 登录失败:", str(e)[:80])

q = urllib.parse.quote(WORD)
try:
    h = opener.open(BASE + "/crawler/?q=" + q, timeout=40).read().decode("utf-8", "ignore")
    m = re.search(r"window\.__BOOT__ = (\{.*?\});</script>", h, re.S)
    if m:
        boot = json.loads(m.group(1))
        items = boot.get("items") or []
        mine = [it for it in items if SITE.split("-")[1] in (it.get("site") or "") or "丹寨" in (it.get("site") or "")]
        print("  /crawler/?q=%s → 首屏 %d 条，其中本站 %d 条" % (WORD, len(items), len(mine)))
        for it in items[:5]:
            print("     ·", (it.get("site") or "?")[:22], "|", (it.get("title") or "")[:36])
    else:
        print("  /crawler/ 未拿到 BOOT（可能未登录成功）")
except Exception as e:
    print("  ❌ /crawler/ 失败:", str(e)[:80])

print("\n=== ③ 详情页渲染（/crawler/project/<id>）===")
row = db.execute("SELECT id, title FROM gov_raw WHERE site_name=? ORDER BY publish_date DESC LIMIT 1",
                 (SITE,)).fetchone()
if row:
    rid, rtitle = row
    try:
        h = opener.open(BASE + "/crawler/project/%s" % rid, timeout=30).read().decode("utf-8", "ignore")
        print("  id=%s HTTP 200 | 字节 %d" % (rid, len(h)))
        print("  含标题:", rtitle[:20] in h)
        print("  含 <p>:", "<p" in h, "| 含 <table>:", "<table" in h)
        print("  含外链 <a href=http:", 'href="http' in h)
        print("  含归档章噪声(已归档/ArchiveGdPart):", ("已归档" in h or "ArchiveGdPart" in h))
    except Exception as e:
        print("  ❌ 详情失败:", str(e)[:80])
db.close()
