"""Tests for the paginated log reader tool."""
import pytest
from armorer.tools.log_reader import store_log, get_log_summary, _read_logs_impl, clear_log, _log_store


@pytest.fixture(autouse=True)
def cleanup_log_store():
    """Ensure the log store is clean before/after each test."""
    _log_store.clear()
    yield
    _log_store.clear()


class TestStoreLog:
    """Verify log storage and session ID generation."""

    def test_returns_session_id(self):
        sid = store_log("line1\nline2\nline3")
        assert sid.startswith("log_")

    def test_stores_lines_correctly(self):
        sid = store_log("alpha\nbeta\ngamma")
        assert _log_store[sid] == ["alpha", "beta", "gamma"]


class TestGetLogSummary:
    """Verify head+tail summary generation."""

    def test_short_log_returns_full_content(self):
        sid = store_log("line1\nline2\nline3")
        summary = get_log_summary(sid, head=10, tail=10)
        assert "line1" in summary
        assert "line2" in summary
        assert "line3" in summary
        assert "hidden" not in summary

    def test_long_log_shows_head_and_tail(self):
        lines = [f"line_{i}" for i in range(200)]
        sid = store_log("\n".join(lines))
        summary = get_log_summary(sid, head=5, tail=5)

        # Head should be present
        assert "line_0" in summary
        assert "line_4" in summary

        # Tail should be present
        assert "line_199" in summary
        assert "line_195" in summary

        # Middle should be hidden
        assert "hidden" in summary
        assert "line_100" not in summary

    def test_gap_indicator_shows_correct_count(self):
        lines = [f"line_{i}" for i in range(100)]
        sid = store_log("\n".join(lines))
        summary = get_log_summary(sid, head=10, tail=10)
        # Should show 80 lines hidden
        assert "80 lines hidden" in summary


class TestReadLogs:
    """Verify paginated log reading."""

    def test_reads_batch_from_start(self):
        lines = [f"line_{i}" for i in range(100)]
        sid = store_log("\n".join(lines))

        # The tool function is decorated with @tool, call it as a regular function
        result = _read_logs_impl(session_id=sid, start_line=1, num_lines=10)
        assert "line_0" in result
        assert "line_9" in result
        assert "Lines 1–10 of 100" in result

    def test_reads_batch_from_middle(self):
        lines = [f"line_{i}" for i in range(100)]
        sid = store_log("\n".join(lines))

        result = _read_logs_impl(session_id=sid, start_line=50, num_lines=10)
        assert "line_49" in result  # 1-indexed: line 50 = index 49
        assert "Lines 50–59 of 100" in result

    def test_caps_at_200_lines(self):
        lines = [f"line_{i}" for i in range(500)]
        sid = store_log("\n".join(lines))

        result = _read_logs_impl(session_id=sid, start_line=1, num_lines=999)
        assert "Lines 1–200 of 500" in result

    def test_invalid_session_returns_error(self):
        result = _read_logs_impl(session_id="nonexistent", start_line=1, num_lines=10)
        assert "Error" in result

    def test_start_beyond_total_returns_error(self):
        sid = store_log("only\ntwo\nlines")
        result = _read_logs_impl(session_id=sid, start_line=100, num_lines=10)
        assert "Error" in result


class TestClearLog:
    """Verify log cleanup."""

    def test_removes_stored_log(self):
        sid = store_log("data")
        assert sid in _log_store
        clear_log(sid)
        assert sid not in _log_store

    def test_clear_nonexistent_is_safe(self):
        clear_log("does_not_exist")  # Should not raise
