#!/usr/bin/env python3
"""
Unit tests for archive_references.py's slugify() and the minimal bib parser,
covering the edge cases that are easy to get wrong silently: CJK topic names
and nested-brace LaTeX field values (e.g. \\ensuremath{\\epsilon}).

Run: python -m unittest discover -s .claude/skills/literature-search-verify/scripts
"""
import os
import sys
import tempfile
import unittest

sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), ".."))
import archive_references as ar


class TestSlugify(unittest.TestCase):
    def test_ascii_topic(self):
        self.assertEqual(ar.slugify("UAV aeromagnetic compensation"), "uav_aeromagnetic_compensation")

    def test_chinese_topic_is_preserved_not_collapsed_to_generic_name(self):
        slug = ar.slugify("无人机磁补偿")
        self.assertNotEqual(slug, "references")
        self.assertIn("补偿", slug)

    def test_mixed_chinese_and_english(self):
        slug = ar.slugify("无人机磁补偿 Tolles-Lawson")
        self.assertTrue(slug.endswith("tolles_lawson"))

    def test_blank_topic_falls_back_to_references(self):
        self.assertEqual(ar.slugify("   "), "references")

    def test_truncated_to_60_chars(self):
        self.assertEqual(len(ar.slugify("a" * 100)), 60)


class TestParseBibEntries(unittest.TestCase):
    def _write_bib(self, content):
        fd, path = tempfile.mkstemp(suffix=".bib")
        with os.fdopen(fd, "w", encoding="utf-8") as f:
            f.write(content)
        self.addCleanup(os.remove, path)
        return path

    def test_nested_braces_in_field_value_do_not_truncate_it(self):
        bib = (
            "@article{wu2017,\n"
            "  title   = {Aeromagnetic gradient compensation using \\ensuremath{\\epsilon}-SVR},\n"
            "  journal = {Journal of Applied Remote Sensing},\n"
            "  year    = {2017},\n"
            "  doi     = {10.1117/1.jrs.11.025012},\n"
            "}"
        )
        entries = ar.parse_bib_entries(self._write_bib(bib))
        self.assertEqual(len(entries), 1)
        self.assertIn("\\ensuremath{\\epsilon}-SVR", entries[0]["title"])
        self.assertEqual(entries[0]["year"], "2017")

    def test_multiple_entries_and_optional_fields(self):
        bib = (
            "@article{a2020,\n"
            "  title = {First paper},\n"
            "  year  = {2020},\n"
            "}\n\n"
            "@article{b2021,\n"
            "  title = {Second paper},\n"
            "  year  = {2021},\n"
            "  note  = {some note},\n"
            "}"
        )
        entries = ar.parse_bib_entries(self._write_bib(bib))
        self.assertEqual([e["key"] for e in entries], ["a2020", "b2021"])
        self.assertNotIn("note", entries[0])
        self.assertEqual(entries[1]["note"], "some note")


class TestYearSortKey(unittest.TestCase):
    def test_entries_without_a_parseable_year_sort_last(self):
        entries = [{"key": "b", "year": ""}, {"key": "a", "year": "1999"}]
        entries.sort(key=ar.year_sort_key)
        self.assertEqual([e["key"] for e in entries], ["a", "b"])


class TestBuildReadme(unittest.TestCase):
    def test_omits_optional_sections_when_not_given(self):
        readme = ar.build_readme("Topic", [], 0, [], None)
        self.assertNotIn("Flagged during search", readme)
        self.assertNotIn("Search coverage notes", readme)

    def test_includes_suspect_and_notes_when_given(self):
        readme = ar.build_readme("Topic", [], 0, ["Bad title|dubious venue"], "coverage notes here")
        self.assertIn("Bad title", readme)
        self.assertIn("dubious venue", readme)
        self.assertIn("coverage notes here", readme)


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