"""Tests for #573 — temporal_marker and temporal persistence through the pipeline."""

import pytest
from unittest.mock import AsyncMock, MagicMock, patch
from cortex.types import SemanticClaim, CandidateClaim
from cortex.extraction.extractor import ClaimExtraction


class TestTemporalFieldsOnDataclasses:
    """Verify temporal and temporal_marker exist on all claim types."""

    def test_candidate_claim_has_temporal(self):
        c = CandidateClaim(subject="x", predicate="y", object_value="z", temporal="past")
        assert c.temporal == "past"

    def test_candidate_claim_has_temporal_marker(self):
        c = CandidateClaim(subject="x", predicate="y", object_value="z", temporal_marker="last week")
        assert c.temporal_marker == "last week"

    def test_candidate_claim_defaults(self):
        c = CandidateClaim(subject="x", predicate="y", object_value="z")
        assert c.temporal == "current"
        assert c.temporal_marker is None

    def test_semantic_claim_has_temporal(self):
        c = SemanticClaim(id="1", owner_id="o", subject="x", predicate="y", object_value="z", temporal="future")
        assert c.temporal == "future"

    def test_semantic_claim_has_temporal_marker(self):
        c = SemanticClaim(id="1", owner_id="o", subject="x", predicate="y", object_value="z", temporal_marker="March 2026")
        assert c.temporal_marker == "March 2026"

    def test_semantic_claim_defaults(self):
        c = SemanticClaim(id="1", owner_id="o", subject="x", predicate="y", object_value="z")
        assert c.temporal == "current"
        assert c.temporal_marker is None


class TestClaimExtractionToCandidate:
    """Verify ClaimExtraction.to_candidate() passes temporal fields through."""

    def test_temporal_forwarded(self):
        ce = ClaimExtraction(
            action="ADD",
            subject="user",
            predicate="visited",
            object_value="Tokyo",
            confidence=0.9,
            temporal="past",
            temporal_marker="last week",
            entities_mentioned=[],
            sensitivity="normal",
            category="personal",
        )
        candidate = ce.to_candidate()
        assert candidate.temporal == "past"
        assert candidate.temporal_marker == "last week"

    def test_temporal_defaults_when_missing(self):
        ce = ClaimExtraction(
            action="ADD",
            subject="user",
            predicate="likes",
            object_value="Python",
            confidence=0.8,
            temporal="current",
            entities_mentioned=[],
            sensitivity="normal",
            category="preferences",
        )
        candidate = ce.to_candidate()
        assert candidate.temporal == "current"
        assert candidate.temporal_marker is None


class TestMigrationV12:
    """Verify v12 migration module structure."""

    def test_migration_has_required_attrs(self):
        from cortex.storage.migrations import v12_temporal_marker as m
        assert m.VERSION == 12
        assert "temporal_marker" in m.SQL_UP
        assert "temporal" in m.SQL_UP
        assert m.DESCRIPTION
        assert hasattr(m, "SQL_DOWN")

    def test_sql_up_adds_both_columns(self):
        from cortex.storage.migrations import v12_temporal_marker as m
        assert "ALTER TABLE semantic_claim ADD COLUMN temporal_marker" in m.SQL_UP
        assert "ALTER TABLE semantic_claim ADD COLUMN temporal TEXT" in m.SQL_UP

    def test_index_created(self):
        from cortex.storage.migrations import v12_temporal_marker as m
        assert "idx_claim_temporal" in m.SQL_UP
