from __future__ import annotations

import sys
import unittest
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parents[1]))

from core.pysyntax import precheck_python  # noqa: E402


class TestPrecheckPython(unittest.TestCase):
    # ── 放行:合法码不误伤 ──
    def test_clean_code_passes(self):
        self.assertIsNone(precheck_python("import os\nx = 1 + 2\nprint(x)\n"))

    def test_valid_chinese_in_string_passes(self):
        """中文正文在正确引号里 = 合法,绝不误报。"""
        self.assertIsNone(precheck_python('x = "中文正文，含全角标点。没问题！"\n'))

    def test_chinese_quotes_in_string_passes(self):
        """中文引号 “” 只是普通字符,不是分隔符,合法。"""
        self.assertIsNone(precheck_python('x = "他说“你好”，然后走了。"\n'))

    def test_empty_and_none_pass(self):
        self.assertIsNone(precheck_python(None))
        self.assertIsNone(precheck_python(""))
        self.assertIsNone(precheck_python("   \n  "))
        self.assertIsNone(precheck_python(123))  # 非字符串

    # ── A 类:中文串里 ASCII 引号提前闭合(样本 #1/#8/#16) ──
    def test_ascii_quote_in_chinese_string(self):
        code = 'T("（5）产学研合作：形成"产学研用"一体化链条。")\n'
        hint = precheck_python(code)
        self.assertIsNotNone(hint)
        self.assertTrue(hint.startswith("[Error]"))
        self.assertIn("第 1 行", hint)
        self.assertIn("引号", hint)  # 定向引号诊断
        self.assertIn("write", hint)  # 根治提示(正文进文件)

    def test_unterminated_string_with_cjk(self):
        code = "set_cell(c, '国际一流双碳大数据平台], '负责人')\n"
        hint = precheck_python(code)
        self.assertIsNotNone(hint)
        self.assertIn("引号", hint)

    # ── B 类:全角标点漏进代码位(样本 #7/#9) ──
    def test_fullwidth_punct_in_code(self):
        code = 'add_h("2025年12月", 14, center=True、name)\n'
        hint = precheck_python(code)
        self.assertIsNotNone(hint)
        self.assertIn("半角", hint)  # 全角→半角定向诊断

    def test_fullwidth_paren_in_code(self):
        code = 'set_cell(tbl, "响应函", "第五章（附件）中的要求。", "通过")\n（\n'
        hint = precheck_python(code)
        self.assertIsNotNone(hint)

    # ── C 类:结构崩坏 ──
    def test_unmatched_bracket(self):
        hint = precheck_python("for i in enumerate(doc.paragraphs[:5()[:80]}'\")\n")
        self.assertIsNotNone(hint)
        self.assertTrue(hint.startswith("[Error]"))

    # ── 非中文语法错:仍拦,但不追加中文根治提示 ──
    def test_non_cjk_syntax_error(self):
        hint = precheck_python("def f(:\n    pass\n")
        self.assertIsNotNone(hint)
        self.assertTrue(hint.startswith("[Error]"))
        self.assertNotIn("write 写进", hint)  # 无中文正文,不追加"别拼中文进 py"

    def test_lineno_reported(self):
        code = "a = 1\nb = 2\nc = @\n"
        hint = precheck_python(code)
        self.assertIsNotNone(hint)
        self.assertIn("第 3 行", hint)


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