#!/usr/bin/env python3
"""Create/update the read-only DBCOMPAT-0021 restart read-back scenario."""

from __future__ import annotations

import copy
import importlib.util
from pathlib import Path


BASE_SCRIPT = Path(
    "/Users/guodongwei/Documents/zhct/zhctprompt/"
    "work_food_safety/2026-09-24-apifox-full-api-automation/"
    "apifox/scripts/sync_school_s00_s06_scenarios.py"
)
SPEC = importlib.util.spec_from_file_location("school_s00_s06_sync", BASE_SCRIPT)
if SPEC is None or SPEC.loader is None:
    raise RuntimeError(f"Cannot load shared Apifox helpers from {BASE_SCRIPT}")
shared = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(shared)


NAME = "S12-R-公告与食堂配置重启读回（专项）"
DESCRIPTION = (
    "DBCOMPAT-0021 关闭门禁专项。只读取网关重启前已经写入的公告、附件元数据和食堂配置，"
    "不新增、不更新、不删除任何数据。MySQL 仅访问 foodsafe_test，达梦仅访问 WWWWEB。"
)


OPERATIONS = [
    {
        "name": "重启后从列表读回原公告",
        "method": "GET",
        "path": "/school/system/announcements?page=1&pageSize=100&schoolId=1",
        "tests": [
            ("重启读回：列表仍包含原公告", "const row=__json.data.items.find(function(x){return x.id===pm.variables.get('restart_announcement_id');}); pm.expect(row).to.exist; pm.expect(row.title).to.equal(pm.variables.get('restart_announcement_title'))"),
            ("重启读回：列表中原附件仍存在", "const row=__json.data.items.find(function(x){return x.id===pm.variables.get('restart_announcement_id');}); pm.expect(row.attachments).to.have.lengthOf(1); pm.expect(row.attachments[0].id).to.equal(pm.variables.get('restart_attachment_id'))"),
        ],
    },
    {
        "name": "重启后从详情读回原公告与附件",
        "method": "GET",
        "path": "/school/system/announcements/detail?id={{restart_announcement_id}}&schoolId=1",
        "tests": [
            ("重启读回：公告 ID、学校和中文正文完整", "pm.expect(__json.data.id).to.equal(pm.variables.get('restart_announcement_id')); pm.expect(Number(__json.data.schoolId)).to.equal(1); pm.expect(__json.data.content).to.equal('请各食堂负责人于本周五前完成秋季食品安全培训，并提交签到记录与现场照片。')"),
            ("重启读回：附件 ID、名称和本地 URL 完整", "pm.expect(__json.data.attachments).to.have.lengthOf(1); const a=__json.data.attachments[0]; pm.expect(a.id).to.equal(pm.variables.get('restart_attachment_id')); pm.expect(a.name).to.equal('2026年秋季食品安全培训签到表（电子回执）.pdf'); pm.expect(a.url).to.equal('/files/announcements/'+pm.variables.get('restart_announcement_id')+'/training-signin-2026-autumn.pdf')"),
        ],
    },
    {
        "name": "重启后读回原食堂配置",
        "method": "GET",
        "path": "/school/system/canteen",
        "tests": [
            ("重启读回：食堂中文字段完整", "pm.expect(__json.data.name).to.equal('康源实验学校第一食堂'); pm.expect(__json.data.manager).to.equal('食品安全总监王建国'); pm.expect(__json.data.phone).to.equal('13601002030'); pm.expect(__json.data.address).to.equal('北京市海淀区书院路18号综合楼一层')"),
            ("重启读回：仍为重启前同一次更新", "const actual=new Date(String(__json.data.updatedAt).replace(' ','T')+'+08:00').getTime(); const expected=new Date(pm.variables.get('restart_canteen_updated_at')).getTime(); pm.expect(Math.abs(actual-expected)).to.be.below(1000)"),
        ],
    },
]


def main() -> None:
    api = shared.Apifox()
    by_name = {item["name"]: item for item in api.scenarios()}
    source = by_name["S00-环境与认证（双库）"]
    source_data = api.scenario(int(source["id"]))
    loop_template = source_data["steps"][0]
    login_template = loop_template["children"][0]
    request_template = loop_template["children"][1]

    current = by_name.get(NAME)
    scenario_id = int(current["id"]) if current else api.duplicate(int(source["id"]))
    scenario = api.scenario(scenario_id)
    scenario.update({"name": NAME, "description": DESCRIPTION, "folderId": shared.FOLDER_ID, "ordering": 125})
    loop = copy.deepcopy(loop_template)
    loop["id"] = shared.new_id()
    loop["number"] = 1
    loop.setdefault("parameters", {})["array"] = '["http://127.0.0.1:3553","http://127.0.0.1:3552"]'
    login = shared.make_login(login_template, "APIFOX_S12_RESTART")
    login_pre = login["customHttpRequest"]["preProcessors"][0]["data"]
    login["customHttpRequest"]["preProcessors"][0]["data"] = login_pre + (
        "const __mysql = pm.variables.get('base_url').endsWith(':3553');\n"
        "pm.variables.set('restart_announcement_id', __mysql ? 'AN-91110a25-72cf-4dec-a851-14c556db514c' : 'AN-440038af-43ec-494c-a473-c416d16d321b');\n"
        "pm.variables.set('restart_attachment_id', __mysql ? 'ATT-2792598e-9b56-4f10-addd-284024d9e23b' : 'ATT-4c0e4371-d164-4ccf-a6ca-b4cc97da8cc4');\n"
        "pm.variables.set('restart_announcement_title', __mysql ? '2026年秋季学校食品安全培训通知（档案20260926738413）' : '2026年秋季学校食品安全培训通知（档案20260926741677）');\n"
        "pm.variables.set('restart_canteen_updated_at', __mysql ? '2026-09-26T05:48:58.772Z' : '2026-09-26T05:49:03.987Z');\n"
    )
    loop["children"] = [login]
    for number, operation in enumerate(OPERATIONS, start=2):
        step = shared.make_request(request_template, **operation)
        step["number"] = number
        loop["children"].append(step)
    scenario["steps"] = [loop]
    api.save(scenario)

    saved = api.scenario(scenario_id)
    requests = shared.flatten_requests(saved["steps"])
    if len(requests) != 1 + len(OPERATIONS):
        raise RuntimeError(f"{NAME}: unexpected request count {len(requests)}")
    if not all(shared.request_has_auditable_evidence(request) for request in requests):
        raise RuntimeError(f"{NAME}: one or more requests lack auditable evidence")
    print(f"{NAME}: id={scenario_id}, readOnlyOperations={len(OPERATIONS)}, totalRequests={len(requests)}")
    print("本专项不加入常规一键套件，仅用于缺陷关闭取证。")


if __name__ == "__main__":
    main()
