#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""守护脚本: 等调度器(crawl_scheduler_v2)结束后, 全量清理荆州正文尾部噪声。

战术依据(crawler-scheduler-v2 skill 锁窗口战术②):
  调度器跑 1600+ 配置可持续 10h+, 期间写锁间歇性持续。直接并发 UPDATE 会被锁饿死。
  等调度器进程退出后再清理, 锁完全空闲, 秒级完成。
"""
import os
import re
import sqlite3
import subprocess
import sys
import time

LOG = "/tmp/jz_guard_clean.log"


def log(msg):
    line = f"[{time.strftime('%H:%M:%S')}] {msg}"
    print(line, flush=True)
    with open(LOG, "a", encoding="utf-8") as f:
        f.write(line + "\n")


def scheduler_running():
    """调度器主进程在跑? (crawl_scheduler_v2.py)"""
    try:
        out = subprocess.run(
            ["pgrep", "-f", "crawl_scheduler_v2"], capture_output=True, text=True, timeout=15
        ).stdout.strip()
        return bool(out)
    except Exception:
        return True  # 保守: 拿不准就当还在跑


def clean(c):
    if not c:
        return c
    c = re.sub(r'<a href="javascript:[^"]*">\s*关闭\s*</a>', '', c)
    c = re.sub(r'<div class="zw-box-print">.*?</div>', '', c, flags=re.DOTALL)
    c = re.sub(
        r'<div class="zw-leader-jl">\s*<h3><span>相关(?:链接|文档|图片|音频|视频)</span></h3>.*?</div>',
        '', c, flags=re.DOTALL)

    def att_clean(m):
        paras = []
        for am in re.finditer(r'<a[^>]*href=[\'"]([^\'"]+)[\'"][^>]*>(.*?)</a>', m.group(0), re.DOTALL):
            href, text = am.group(1).strip(), re.sub(r'<[^>]+>', '', am.group(2)).strip()
            if href and text:
                paras.append('<p><a href="{}">{}</a></p>'.format(href, text))
        return '\n'.join(paras)

    c = re.sub(
        r'<div class="zw-leader-jl">\s*<h3><span>相关附件</span></h3>.*?</div>',
        att_clean, c, flags=re.DOTALL)
    return c


def main():
    log("守护脚本启动, 等待调度器结束...")
    waited = 0
    while scheduler_running():
        time.sleep(120)
        waited += 2
        if waited % 10 == 0:
            log(f"  已等待 {waited} 分钟, 调度器仍在运行")

    log(f"调度器已结束(等待 {waited} 分钟), 开始全量清理")
    conn = sqlite3.connect("/mnt/data/search.db", timeout=60)
    conn.execute("PRAGMA busy_timeout=60000")
    rows = conn.execute(
        "SELECT id, content FROM gov_raw WHERE site_name='荆州市生态环境局' AND "
        "(content LIKE '%相关链接%' OR content LIKE '%zw-box-print%' OR content LIKE '%zw-leader-jl%')"
    ).fetchall()
    total = len(rows)
    log(f"待清理: {total} 条")
    updated = 0
    for i, (rid, content) in enumerate(rows, 1):
        nc = clean(content)
        if nc != content:
            conn.execute("UPDATE gov_raw SET content=? WHERE id=?", (nc, rid))
            conn.commit()
            updated += 1
        if i % 500 == 0:
            log(f"  ...{i}/{total} 更新{updated}")
    log(f"完成: 清理 {updated}/{total}")

    # 验证栩辰
    for rid in (42136, 42315, 42352):
        r = conn.execute(
            "SELECT length(content), content LIKE '%相关链接%' FROM gov_raw WHERE id=?", (rid,)
        ).fetchone()
        if r:
            log(f"栩辰 {rid}: {r[0]}字 含噪声:{r[1]}")
    conn.close()


if __name__ == "__main__":
    main()
