"""Tests for ConversationLog — real SQLite, temp directory."""

import time

import pytest

from neo_cortex.conversation_log import ConversationLog
from neo_cortex.models import ConversationAppendRequest


@pytest.fixture
def log(tmp_path) -> ConversationLog:
    return ConversationLog(str(tmp_path / "test.db"))


class TestConversationLogAppend:
    def test_append_and_count(self, log):
        assert log.count() == 0
        req = ConversationAppendRequest(
            session_id="s1", role="user", content="Hello",
        )
        row_id = log.append(req)
        assert row_id == 1
        assert log.count() == 1

    def test_append_multiple(self, log):
        for i in range(5):
            log.append(ConversationAppendRequest(
                session_id="s1", role="user", content=f"msg {i}",
            ))
        assert log.count() == 5

    def test_append_with_metadata(self, log):
        req = ConversationAppendRequest(
            session_id="s1", role="tool_use", content="Read",
            event_type="ToolUseEvent", model="opus",
            metadata={"tool_id": "abc123", "input": "/home/file.py"},
        )
        log.append(req)
        entries = log.get_session("s1")
        assert len(entries) == 1
        assert entries[0].metadata == {"tool_id": "abc123", "input": "/home/file.py"}
        assert entries[0].event_type == "ToolUseEvent"

    def test_append_preserves_timestamp(self, log):
        ts = 1700000000.0
        log.append(ConversationAppendRequest(
            session_id="s1", role="user", content="test", timestamp=ts,
        ))
        entries = log.get_session("s1")
        assert entries[0].timestamp == ts

    def test_append_auto_timestamp(self, log):
        before = time.time()
        log.append(ConversationAppendRequest(
            session_id="s1", role="user", content="test",
        ))
        after = time.time()
        entries = log.get_session("s1")
        assert before <= entries[0].timestamp <= after


class TestConversationLogQuery:
    def test_get_session_ordered(self, log):
        log.append(ConversationAppendRequest(
            session_id="s1", role="user", content="first", timestamp=1.0,
        ))
        log.append(ConversationAppendRequest(
            session_id="s1", role="assistant", content="second", timestamp=2.0,
        ))
        log.append(ConversationAppendRequest(
            session_id="s1", role="user", content="third", timestamp=3.0,
        ))
        entries = log.get_session("s1")
        assert len(entries) == 3
        assert entries[0].content == "first"
        assert entries[1].content == "second"
        assert entries[2].content == "third"

    def test_get_session_isolates_sessions(self, log):
        log.append(ConversationAppendRequest(
            session_id="s1", role="user", content="s1 msg",
        ))
        log.append(ConversationAppendRequest(
            session_id="s2", role="user", content="s2 msg",
        ))
        entries = log.get_session("s1")
        assert len(entries) == 1
        assert entries[0].content == "s1 msg"

    def test_get_recent(self, log):
        for i in range(10):
            log.append(ConversationAppendRequest(
                session_id="s1", role="user", content=f"msg {i}",
                timestamp=float(i + 1),  # 1..10 to avoid 0
            ))
        recent = log.get_recent(3)
        assert len(recent) == 3
        # Should be in chronological order (oldest first of the recent 3)
        assert recent[0].content == "msg 7"
        assert recent[1].content == "msg 8"
        assert recent[2].content == "msg 9"

    def test_get_sessions_list(self, log):
        log.append(ConversationAppendRequest(
            session_id="s1", role="user", content="a", timestamp=1.0,
        ))
        log.append(ConversationAppendRequest(
            session_id="s1", role="assistant", content="b", timestamp=2.0,
        ))
        log.append(ConversationAppendRequest(
            session_id="s2", role="user", content="c", timestamp=3.0,
        ))
        sessions = log.get_sessions()
        assert len(sessions) == 2
        # Most recent session first
        assert sessions[0]["session_id"] == "s2"
        assert sessions[0]["entries"] == 1
        assert sessions[1]["session_id"] == "s1"
        assert sessions[1]["entries"] == 2

    def test_empty_session_returns_empty(self, log):
        assert log.get_session("nonexistent") == []

    def test_all_roles_stored(self, log):
        roles = ["user", "assistant", "tool_use", "tool_result", "system", "error"]
        for role in roles:
            log.append(ConversationAppendRequest(
                session_id="s1", role=role, content=f"{role} content",
            ))
        entries = log.get_session("s1")
        assert [e.role for e in entries] == roles
