"""Tests for Build BC Phase 6: project_type predicate migration.

Verifies:
  1. project_type is the authoritative field (mode is a derived alias).
  2. New predicates (is_client_deliverable, supports_episodes, expects_beat_structure).
  3. Existing predicates behave identically after migrating from self.mode to
     self._project_type_enum.
  4. Legacy `mode` slot is still populated for backward compat.
"""

from __future__ import annotations


from recoil.core.project import (
    ProjectMode,
    ProjectType,
    get_project,
)


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------

def _clear():
    """Clear the lru_cache so each test gets a fresh Project instance."""
    get_project.cache_clear()


# ---------------------------------------------------------------------------
# 1. project_type is authoritative
# ---------------------------------------------------------------------------

class TestProjectTypeAuthoritative:
    """driver-beware has project_type=client_video; tartarus has microdrama."""

    def setup_method(self):
        _clear()

    def teardown_method(self):
        _clear()

    def test_driver_beware_is_client_video(self):
        p = get_project("driver-beware")
        assert p._project_type_enum == ProjectType.CLIENT_VIDEO

    def test_tartarus_is_microdrama(self):
        p = get_project("tartarus")
        assert p._project_type_enum == ProjectType.MICRODRAMA

    def test_driver_beware_project_type_string(self):
        p = get_project("driver-beware")
        assert p.project_type == "client_video"

    def test_tartarus_project_type_string(self):
        p = get_project("tartarus")
        assert p.project_type == "microdrama"


# ---------------------------------------------------------------------------
# 2. New predicates
# ---------------------------------------------------------------------------

class TestNewPredicates:
    """is_client_deliverable, supports_episodes, expects_beat_structure."""

    def setup_method(self):
        _clear()

    def teardown_method(self):
        _clear()

    def test_driver_beware_is_client_deliverable(self):
        p = get_project("driver-beware")
        assert p.is_client_deliverable is True

    def test_tartarus_is_not_client_deliverable(self):
        p = get_project("tartarus")
        assert p.is_client_deliverable is False

    def test_tartarus_supports_episodes(self):
        p = get_project("tartarus")
        assert p.supports_episodes is True

    def test_driver_beware_does_not_support_episodes(self):
        p = get_project("driver-beware")
        assert p.supports_episodes is False

    def test_tartarus_expects_beat_structure(self):
        p = get_project("tartarus")
        assert p.expects_beat_structure is True

    def test_driver_beware_does_not_expect_beat_structure(self):
        p = get_project("driver-beware")
        assert p.expects_beat_structure is False


# ---------------------------------------------------------------------------
# 3. Existing predicates — behavior-preserving after migration
# ---------------------------------------------------------------------------

class TestExistingPredicatesBehaviorPreserving:
    """Migrated predicates must behave identically to pre-Phase-6 behavior."""

    def setup_method(self):
        _clear()

    def teardown_method(self):
        _clear()

    def test_tartarus_uses_pass_naming(self):
        p = get_project("tartarus")
        assert p.uses_pass_naming is True

    def test_driver_beware_not_uses_pass_naming(self):
        p = get_project("driver-beware")
        assert p.uses_pass_naming is False

    def test_tartarus_sweeps_orphans(self):
        p = get_project("tartarus")
        assert p.sweeps_orphans is True

    def test_driver_beware_not_sweeps_orphans(self):
        p = get_project("driver-beware")
        assert p.sweeps_orphans is False

    def test_tartarus_uses_pass_store(self):
        p = get_project("tartarus")
        assert p.uses_pass_store is True

    def test_driver_beware_not_uses_pass_store(self):
        p = get_project("driver-beware")
        assert p.uses_pass_store is False

    def test_tartarus_auto_extracts_segments(self):
        p = get_project("tartarus")
        assert p.auto_extracts_segments is True

    def test_driver_beware_not_auto_extracts_segments(self):
        p = get_project("driver-beware")
        assert p.auto_extracts_segments is False

    def test_tartarus_captures_verdicts(self):
        """Microdrama captures verdicts."""
        p = get_project("tartarus")
        assert p.captures_verdicts is True

    def test_driver_beware_captures_verdicts(self):
        """client_video now captures verdicts (widened in Phase 6)."""
        p = get_project("driver-beware")
        assert p.captures_verdicts is True

    def test_tartarus_has_take_semantics(self):
        p = get_project("tartarus")
        assert p.has_take_semantics is True

    def test_driver_beware_not_has_take_semantics(self):
        p = get_project("driver-beware")
        assert p.has_take_semantics is False

    def test_tartarus_ui_grouping_pass_anchors(self):
        p = get_project("tartarus")
        assert p.ui_grouping_strategy == "pass_anchors"

    def test_driver_beware_ui_grouping_flat(self):
        p = get_project("driver-beware")
        assert p.ui_grouping_strategy == "flat"


# ---------------------------------------------------------------------------
# 4. Legacy `mode` slot backward compat
# ---------------------------------------------------------------------------

class TestModeBackcompat:
    """mode slot must still be populated with a ProjectMode value."""

    def setup_method(self):
        _clear()

    def teardown_method(self):
        _clear()

    def test_tartarus_mode_is_microdrama(self):
        p = get_project("tartarus")
        assert p.mode == ProjectMode.MICRODRAMA

    def test_driver_beware_mode_is_client_deliverable(self):
        """client_video maps to ProjectMode.CLIENT_DELIVERABLE in legacy slot."""
        p = get_project("driver-beware")
        assert p.mode == ProjectMode.CLIENT_DELIVERABLE

    def test_mode_slot_is_project_mode_instance(self):
        """mode is always a ProjectMode instance, not a plain string."""
        p = get_project("tartarus")
        assert isinstance(p.mode, ProjectMode)

    def test_mode_string_comparison_still_works(self):
        """ProjectMode(str, Enum) means == "microdrama" still evaluates True."""
        p = get_project("tartarus")
        assert p.mode == "microdrama"
