#!/usr/bin/env python3
"""Portable tests for the formal DOCX preservation audit."""

from __future__ import annotations

import importlib.util
import sys
import tempfile
import unittest
import zipfile
from pathlib import Path


SCRIPT = Path(__file__).parents[1] / "scripts" / "audit_docx_format_preservation.py"
SPEC = importlib.util.spec_from_file_location("docx_audit", SCRIPT)
MODULE = importlib.util.module_from_spec(SPEC)
assert SPEC and SPEC.loader
sys.modules[SPEC.name] = MODULE
SPEC.loader.exec_module(MODULE)

W_NS = "http://schemas.openxmlformats.org/wordprocessingml/2006/main"


def make_package(path: Path, text: str, styles: str = "<styles/>") -> None:
    document = f"""<?xml version="1.0" encoding="UTF-8"?>
<w:document xmlns:w="{W_NS}"><w:body><w:p><w:pPr><w:pStyle w:val="2"/></w:pPr><w:r><w:t>{text}</w:t></w:r></w:p></w:body></w:document>"""
    with zipfile.ZipFile(path, "w") as package:
        package.writestr("word/document.xml", document)
        package.writestr("word/styles.xml", styles)


class AuditTests(unittest.TestCase):
    def test_unchanged_package_passes(self) -> None:
        with tempfile.TemporaryDirectory() as directory:
            source = Path(directory) / "source.docx"
            make_package(source, "项目背景")
            report = MODULE.audit(source, source, set(), False)
            self.assertEqual(report["result"], "PASS")
            self.assertEqual(report["failures"], [])

    def test_body_text_in_short_styled_paragraph_fails(self) -> None:
        with tempfile.TemporaryDirectory() as directory:
            source = Path(directory) / "source.docx"
            edited = Path(directory) / "edited.docx"
            make_package(source, "项目背景")
            make_package(
                edited,
                "二是管理依据。项目按照正式文件审查、数据目录、网络安全和密码应用要求组织建设和验收，并保留完整的过程记录、测试结果与交付证据。",
                "<styles><style/></styles>",
            )
            report = MODULE.audit(source, edited, set(), False)
            kinds = {failure["kind"] for failure in report["failures"]}
            self.assertEqual(report["result"], "FAIL")
            self.assertIn("guarded_package_part_changed", kinds)
            self.assertIn("body_text_replaced_short_styled_paragraph", kinds)


if __name__ == "__main__":
    unittest.main()
