#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
模块名称：verify_smart_locate_semantic.py
模块描述：智能定位语义化生成端到端验证脚本（阶段6语义化用例生成器）

在真实被测系统上运行 SmartLocateService.locate_steps，验证：
- 静态步骤走语义解析优先路径（产出 semantic）
- "xxx选择/切换为：值" 模式步骤产出 row_checkbox/tab semantic + contains CTX
- 动态 fill 步骤值 CTX 化 → parameters 初值
- 点击弹窗步骤条件生成 verify
- 全流程不产生业务数据副作用（在"确定创建"之前停止）

用法：
    cd backend && python scripts/verify_smart_locate_semantic.py

作者：czj
创建日期：2026-08-18
"""

import io
import logging
import sys
from typing import Any, Dict, List

logging.basicConfig(level=logging.INFO, format="%(asctime)s %(name)s %(message)s")
logger = logging.getLogger("verify_semantic")

sys.path.insert(0, ".")


def main() -> None:
    from app.services.smart_locate_service import SmartLocateService

    steps: List[Dict[str, Any]] = [
        # ===== 导航步骤（显式稳定选择器，聚焦语义生成验收而非导航智能） =====
        # 名称避开 dialog 关键词（新建/创建/新增…），否则 _execute_step 会等待弹窗而
        # 实际是页面跳转（CreateMeeting 为整页路由，无 .el-dialog/.el-drawer）→ 假失败
        {"order": 1, "name": "点击【功能中心】展开", "action": "click",
         "params": {"selector": '//*[@id="Home"]/div[1]/div[1]'}},
        {"order": 2, "name": "进入会议模块", "action": "click",
         "params": {"selector": '.el-drawer [data-key="reserve_list.create"]'}},
        {"order": 3, "name": "等待会议表单加载", "action": "wait",
         "params": {"selector": "input[placeholder*='会议名称']", "timeout": 10000}},

        # ===== 表单步骤（无选择器 → 智能定位语义化生成验收核心） =====
        # 4/7 动态 fill：keyword 定位 → 反向生成 input semantic + 值 CTX 化 → parameters 初值
        # 5/6 "xxx：值" 模式 click：keyword 定位 → 反向生成 row_checkbox/tab semantic
        #   + contains CTX 化
        {"order": 4, "name": "填写会议名称", "action": "fill",
         "params": {"value": "智能定位验收自动会议X"}},
        {"order": 5, "name": "会议室选择：北京展厅会议室", "action": "click", "params": {}},
        {"order": 6, "name": "时间切换为：预定会议", "action": "click", "params": {}},
        {"order": 7, "name": "输入会议议题", "action": "fill",
         "params": {"value": "智能定位验收测试议题"}},
    ]

    logger.info("=== 启动智能定位（真实系统 %s）===", "https://192.168.5.44")
    service = SmartLocateService()
    # navigate_menu 留空：由步骤自身完成"功能中心→会议模块"导航，
    # 避免与 navigate_menu 的预导航冲突（后者已展开菜单，再点功能中心会失效）
    results = service.locate_steps(
        steps=steps,
        auto_login=True,
        navigate_menu="",
        page_url="https://192.168.5.44",
        use_claude=False,  # 规则优先，验证语义生成而非 Claude
    )

    out: List[str] = []
    out.append("")
    out.append("=== 定位结果 ===")
    for r in results:
        ok = r.get("success")
        sem = r.get("semantic")
        ver = r.get("verify")
        out.append(
            f"#{r.get('order')} {r.get('name')}"
            f" | action={r.get('action')} | {'OK' if ok else 'FAIL'}"
        )
        if ok and r.get('selectors', {}).get('primary'):
            out.append(f"     selector: {r['selectors']['primary']}")
        if sem:
            out.append(f"     semantic: {sem}")
        if ver:
            out.append(f"     verify:   {ver}")
        if ok and r.get('params', {}).get('value'):
            out.append(f"     params.value: {r['params']['value']}")

    out.append("")
    out.append("=== 动态数据参数初值 (collected_parameters) ===")
    for k, v in service.collected_parameters.items():
        out.append(f"     {k}: {v}")

    # ===== 断言汇总 =====
    ok_count = sum(1 for r in results if r.get('success'))
    sem_count = sum(1 for r in results if r.get('semantic'))
    out.append("")
    out.append(f"=== 统计: 成功 {ok_count}/{len(results)}, 含 semantic {sem_count} ===")

    io.open("_verify_semantic_out.txt", "w", encoding="utf-8").write("\n".join(out))
    logger.info("输出已写入 _verify_semantic_out.txt")
    for line in out:
        print(line)


if __name__ == "__main__":
    main()
