"""Synthetic parser checks. Run: python3 -m unittest discover -s public -v"""
import tempfile
import unittest
import xml.etree.ElementTree as ET
import json
from pathlib import Path

from analyze import analyze, individual_flags, is_full_date, ofac_flags, present, run, uk_flags


class AvailabilityTests(unittest.TestCase):
    def test_date_precision_and_calendar_validity(self):
        self.assertTrue(is_full_date("29 Feb 2000", "ofac-sdn"))
        self.assertTrue(is_full_date("29/02/2000", "uk-sanctions"))
        for value in ("29 Feb 2001", "circa 01 Jan 1970", "1970", "01 Jan 1970 to 31 Dec 1970"):
            self.assertFalse(is_full_date(value, "ofac-sdn"))
        for value in ("29/02/2001", "dd/mm/1970", "12/03/19yy", "00/00/1970", "1970"):
            self.assertFalse(is_full_date(value, "uk-sanctions"))

    def test_multiple_dob_values_count_record_once(self):
        flags = individual_flags(["1970", "01 Jan 1971"], False, False, False, "ofac-sdn")
        self.assertTrue(flags["dob_at_least_one_full_calendar_date"])
        self.assertFalse(flags["dob_present_no_full_calendar_date"])
        self.assertTrue(flags["multiple_dob_values"])

    def test_empty_and_explicit_placeholders(self):
        for value in (None, "", "   ", " n/a ", "Unknown", "not known"):
            self.assertFalse(present(value))
        self.assertTrue(present("dd/mm/1970"))

    def test_ofac_generic_id_list_is_not_a_passport(self):
        record = ET.fromstring("<sdnEntry><sdnType>Individual</sdnType><idList><id><idType>Gender</idType><idNumber>Test</idNumber></id></idList></sdnEntry>")
        flags = ofac_flags(record)
        self.assertFalse(flags["passport_number_present"])
        self.assertTrue(flags["neither_dob_nor_passport_number"])

    def test_ofac_passport_requires_value_but_includes_typed_variants(self):
        record = ET.fromstring("<sdnEntry><sdnType>Individual</sdnType><idList><id><idType>Passport</idType><idNumber>unknown</idNumber></id><id><idType>Diplomatic Passport</idType><idNumber>SYNTHETIC</idNumber></id></idList></sdnEntry>")
        self.assertTrue(ofac_flags(record)["passport_number_present"])

    def test_uk_aliases_and_variations_stay_distinct_case_insensitive(self):
        record = ET.fromstring("<Designation><IndividualEntityShip>Individual</IndividualEntityShip><Names><Name><Name6>Synthetic</Name6><NameType>Primary name variation</NameType></Name></Names></Designation>")
        flags = uk_flags(record)
        self.assertFalse(flags["alias_present"])
        self.assertTrue(flags["primary_name_variation_present"])
        self.assertTrue(flags["alias_or_primary_variation_present"])
        record.find("Names/Name/NameType").text = "ALias"
        self.assertTrue(uk_flags(record)["alias_present"])

    def test_uk_empty_name_not_counted(self):
        record = ET.fromstring("<Designation><IndividualEntityShip>Entity</IndividualEntityShip><Names><Name><NameType>Alias</NameType></Name></Names></Designation>")
        self.assertFalse(uk_flags(record)["alias_present"])
        self.assertNotIn("dob_present", uk_flags(record))

    def test_duplicate_record_ids_fail(self):
        xml = "<Designations><DateGenerated>01/01/2000</DateGenerated>" + "<Designation><UniqueID>TEST</UniqueID><IndividualEntityShip>Individual</IndividualEntityShip></Designation>" * 2 + "</Designations>"
        with tempfile.TemporaryDirectory() as directory:
            path = Path(directory) / "synthetic.xml"
            path.write_text(xml)
            with self.assertRaisesRegex(AssertionError, "duplicate"):
                analyze("uk-sanctions", path)

    def test_ofac_publisher_count_mismatch_fails(self):
        xml = "<sdnList><publshInformation><Record_Count>2</Record_Count></publshInformation><sdnEntry><uid>TEST</uid><sdnType>Individual</sdnType></sdnEntry></sdnList>"
        with tempfile.TemporaryDirectory() as directory:
            path = Path(directory) / "synthetic.xml"
            path.write_text(xml)
            with self.assertRaisesRegex(AssertionError, "count mismatch"):
                analyze("ofac-sdn", path)

    def test_replaced_snapshot_hash_fails_before_analysis(self):
        with tempfile.TemporaryDirectory() as directory:
            base = Path(directory)
            data = base / "input.xml"
            data.write_text("<newSnapshot />")
            manifest = base / "manifest.json"
            manifest.write_text(json.dumps({"snapshots": [{"key": "ofac-sdn", "sha256": "0" * 64}]}))
            with self.assertRaisesRegex(ValueError, "SHA-256 differs"):
                run(data, data, manifest, base / "out")
            self.assertFalse((base / "out").exists())


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