"""测试 M73 偏移模板（M73 Offset Template）的生成与应用。

验证内容：
- 模板应用结果与先前正则替换实现的语义一致
- 不含 M73 指令的 G-code 返回原始文本不做修改
"""
from __future__ import annotations

import unittest

from a1_swap_mod_packer.gcode import M73_RE, apply_plate_number_offset, prepare_m73_offset_template


class M73OffsetTemplateTest(unittest.TestCase):
    """测试 M73 剩余时间偏移模板的正确性。"""

    def test_template_matches_previous_regex_replacement_semantics(self) -> None:
        """验证新模板方式生成的偏移结果与旧正则替换方式完全一致。"""
        gcode = (
            "M73 P0 R10\n"
            "; M73 P0 R20\n"  # 被注释的 M73 行不应匹配
            " M73 P0 R30\n"  # 带前导空格的 M73 行
            "M73 P50 R5999 ; comment\n"  # 带注释的 M73 行
            "G1 X1\n"  # 非 M73 行
            "M73 P100 R0\n"  # 剩余时间为 0 的 M73 行
        )

        def previous_apply(text: str, plate_number: int) -> str:
            """旧版正则替换实现：对每个匹配的 M73 行增加时间偏移。"""
            minute_offset = plate_number * 100 * 60  # 每板偏移 100 分钟

            def replace(match) -> str:
                prefix = match.group(1)
                remaining_minutes = int(match.group(2)) + minute_offset
                suffix = match.group(3)
                return f"{prefix}{remaining_minutes}{suffix}"

            return M73_RE.sub(replace, text)

        # 生成模板并与旧实现逐板对比
        template = prepare_m73_offset_template(gcode)
        for plate_number in (1, 2, 10):
            self.assertEqual(template.apply(plate_number), previous_apply(gcode, plate_number))
            self.assertEqual(apply_plate_number_offset(gcode, plate_number), previous_apply(gcode, plate_number))

    def test_template_without_m73_matches_returns_original_text(self) -> None:
        """验证不含 M73 指令的 G-code 应用模板后保持原样。"""
        gcode = "G1 X1\n; M73 P0 R10\n"  # M73 在注释中，不应匹配
        template = prepare_m73_offset_template(gcode)
        self.assertEqual(template.apply(3), gcode)


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