"""test_python_modules.py — Sanity checks for Python shim modules.

Tests that each module can be imported and key functions run without error.
For deterministic modules, checks that output matches expected values.
"""

from __future__ import annotations

import sys
import unittest
from pathlib import Path

sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "python"))
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "qubo"))


class TestPistBraidBridge(unittest.TestCase):
    """pist_braid_bridge: PIST trace → braid strand mapping."""

    def test_import(self):
        import pist_braid_bridge
        self.assertTrue(hasattr(pist_braid_bridge, "float_to_q16"))
        self.assertTrue(hasattr(pist_braid_bridge, "q16_to_float"))


class TestSidonAddress(unittest.TestCase):
    """sidon_address: Sidon label propagation."""

    def test_import(self):
        import sidon_address
        self.assertTrue(hasattr(sidon_address, "verify_sidon_property"))
        self.assertTrue(hasattr(sidon_address, "spectral_to_sidon_address"))


class TestSpectralProfile(unittest.TestCase):
    """spectral_profile: spectral feature extraction."""

    def test_import(self):
        import spectral_profile
        self.assertTrue(hasattr(spectral_profile, "compute_spectral_profile"))


class TestBuildManifold(unittest.TestCase):
    """build_manifold: manifold generation pipeline."""

    def test_lean_q16_16(self):
        from build_manifold import lean_q16_16
        self.assertEqual(lean_q16_16(0.0), "Q16_16.zero")
        self.assertEqual(lean_q16_16(0.5), "Q16_16.ofRatio 1 2")
        self.assertEqual(lean_q16_16(0.25), "Q16_16.ofRatio 1 4")


class TestQ16Canonical(unittest.TestCase):
    """q16_canonical: Q16_16 encoding/decoding."""

    def test_import(self):
        import q16_canonical
        self.assertTrue(hasattr(q16_canonical, "float_to_q16"))
        self.assertTrue(hasattr(q16_canonical, "q16_to_float"))


class TestDnaCodec(unittest.TestCase):
    """dna_codec: DNA ↔ binary codec."""

    def test_import(self):
        import dna_codec
        self.assertTrue(hasattr(dna_codec, "melting_temperature"))


class TestExprTree(unittest.TestCase):
    """expr_tree: expression tree parsing."""

    def test_import(self):
        import expr_tree
        self.assertTrue(hasattr(expr_tree, "ExprNode"))


class TestBuildPistMatrices(unittest.TestCase):
    """build_pist_matrices_250: PIST matrix generation."""

    def test_import(self):
        import build_pist_matrices_250
        self.assertTrue(hasattr(build_pist_matrices_250, "lean_str"))


class TestDnaQuboSort(unittest.TestCase):
    """dna_qubo_sort: QUBO-based DNA sorting."""

    def test_import(self):
        import dna_qubo_sort
        self.assertTrue(hasattr(dna_qubo_sort, "QuboDnaCandidate"))


class TestChaosGame(unittest.TestCase):
    """chaos_game: chaos game IFS engine."""

    def test_import(self):
        import chaos_game
        self.assertTrue(hasattr(chaos_game, "LCG"))


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