#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
TSA AIGC 认证展示 Demo 启动脚本
- 启动前自动扫描 images/ 目录生成 manifest.json（widget 据此动态加载）
- 启动本地 HTTP 服务
- 自动打开默认浏览器
- Ctrl+C 退出
"""
import http.server
import json
import socketserver
import sys
import time
import webbrowser
import os
from pathlib import Path

PORT = 8765
HOST = "127.0.0.1"
ROOT = Path(__file__).resolve().parent
IMAGES_DIR = ROOT / "images"
URL = f"http://{HOST}:{PORT}/tsa-verification-widget.html"

# 支持的图片后缀（小写匹配）
IMG_EXTS = {".jpg", ".jpeg", ".png", ".webp"}



class QuietHandler(http.server.SimpleHTTPRequestHandler):
    """静默版处理器：拦截 manifest 请求实时扫描目录。"""

    def log_message(self, format, *args):
        if args and len(args) > 0 and "200" not in str(args[0]):
            super().log_message(format, *args)

    def end_headers(self):
        # 防止浏览器缓存导致改了 HTML 看不到效果
        self.send_header("Cache-Control", "no-store, no-cache, must-revalidate")
        self.send_header("Pragma", "no-cache")
        self.send_header("Expires", "0")
        super().end_headers()

    def do_GET(self):
        # /images/manifest.json  → 实时扫描目录生成 JSON
        if self.path.split("?")[0] == "/images/manifest.json":
            items = scan_images()
            payload = {
                "generated_at": int(time.time()),
                "count": len(items),
                "images": items,
            }
            body = json.dumps(payload, ensure_ascii=False).encode("utf-8")
            self.send_response(200)
            self.send_header("Content-Type", "application/json; charset=utf-8")
            self.send_header("Content-Length", str(len(body)))
            self.end_headers()
            self.wfile.write(body)
            return
        return super().do_GET()


def scan_images():
    """实时扫描 images/ 目录（不写文件）。"""
    if not IMAGES_DIR.exists():
        return []
    items = []
    for f in sorted(IMAGES_DIR.iterdir(), key=lambda p: p.name.lower()):
        if not f.is_file():
            continue
        if f.suffix.lower() not in IMG_EXTS:
            continue
        if f.name.startswith(".") or f.name.startswith("__"):
            continue
        items.append({
            "name": f.name,
            "title": f.stem,
            "mtime": int(f.stat().st_mtime),
        })
    return items


def main():
    os.chdir(ROOT)
    items = scan_images()
    print("=" * 60)
    print(f"  TSA AIGC 认证展示 Demo")
    print(f"  本地服务: http://{HOST}:{PORT}")
    print(f"  预览页  : {URL}")
    print(f"  工作目录: {ROOT}")
    print(f"  images/ 共 {len(items)} 张图片：")
    for i, it in enumerate(items, 1):
        size_kb = (IMAGES_DIR / it["name"]).stat().st_size // 1024
        print(f"    {i:>2}. {it['name']:<28} {size_kb:>5} KB")
    print(f"  扫描策略: 实时（请求 /images/manifest.json 时重扫，无需重启）")
    print("=" * 60)
    print("  提示：放入/删除图片后，浏览器刷新即可看到新清单。")
    print("  Ctrl+C 停止服务")
    print()

    with socketserver.TCPServer((HOST, PORT), QuietHandler) as httpd:
        httpd.allow_reuse_address = True
        try:
            webbrowser.open(URL)
        except Exception as e:
            print(f"[WARN] 自动打开浏览器失败: {e}\n请手动访问: {URL}")
        try:
            httpd.serve_forever()
        except KeyboardInterrupt:
            print("\n[INFO] 服务已停止，再见。")


if __name__ == "__main__":
    try:
        main()
    except OSError as e:
        if e.errno == 10048 or "address already in use" in str(e).lower():
            print(f"[ERROR] 端口 {PORT} 已被占用，请先关闭其他占用进程。")
            sys.exit(1)
        raise
