"""Tests for context monitor."""

import json
import tempfile
from pathlib import Path

import pytest

from oclawma.self_improvement.context_monitor import ContextMonitor


class TestContextMonitor:
    """Tests for ContextMonitor."""

    @pytest.fixture
    def temp_dir(self):
        """Create temporary directory for tests."""
        with tempfile.TemporaryDirectory() as tmp:
            yield Path(tmp)

    @pytest.fixture
    def monitor(self, temp_dir):
        """Create monitor with temp path."""
        return ContextMonitor(
            log_file=str(temp_dir / "context.json"),
            warn_threshold=0.7,
            urgent_threshold=0.85,
            critical_threshold=0.95,
        )

    def test_estimate_tokens(self):
        """Test token estimation."""
        monitor = ContextMonitor()

        # String
        tokens = monitor.estimate_tokens("Hello world")
        assert tokens > 0

        # Dict
        tokens = monitor.estimate_tokens({"key": "value"})
        assert tokens > 0

        # List
        tokens = monitor.estimate_tokens([1, 2, 3])
        assert tokens > 0

    def test_check_context_ok(self, monitor):
        """Test context check - OK status."""
        result = monitor.check_context(50000, 128000)

        assert result.status == "ok"
        assert result.percent < 70
        assert result.message is None
        assert len(result.actions) == 0

    def test_check_context_warning(self, monitor):
        """Test context check - Warning status."""
        result = monitor.check_context(90000, 128000)  # ~70%

        assert result.status == "warning"
        assert result.percent >= 70
        assert result.message is not None
        assert len(result.actions) > 0

    def test_check_context_urgent(self, monitor):
        """Test context check - Urgent status."""
        result = monitor.check_context(110000, 128000)  # ~86%

        assert result.status == "urgent"
        assert result.percent >= 85
        assert "archive" in result.message.lower() or "drop" in str(result.actions).lower()

    def test_check_context_critical(self, monitor):
        """Test context check - Critical status."""
        result = monitor.check_context(122000, 128000)  # ~95%

        assert result.status == "critical"
        assert result.percent >= 95
        assert "immediate" in str(result.actions).lower() or "archive" in result.message.lower()

    def test_log_usage(self, monitor, temp_dir):
        """Test logging usage."""
        monitor.log_usage("session-1", 50000, "ok")

        data = json.loads((temp_dir / "context.json").read_text())
        assert len(data["sessions"]) == 1
        assert data["sessions"][0]["sessionId"] == "session-1"
        assert data["totalTokens"] == 50000

    def test_get_compression_tips(self, monitor):
        """Test compression tips generation."""
        files = {
            "large.txt": {"tokens": 5000},
            "small.txt": {"tokens": 100},
            "huge.txt": {"tokens": 10000},
        }

        tips = monitor.get_compression_tips(files)

        assert len(tips) == 2  # Only files > 1000 tokens
        assert "large.txt" in tips[1]
        assert "huge.txt" in tips[0]

    def test_load_save_history(self, monitor, temp_dir):
        """Test loading and saving history."""
        # Log some data
        monitor.log_usage("session-1", 10000, "ok")

        # Create new monitor with same file
        monitor2 = ContextMonitor(log_file=str(temp_dir / "context.json"))
        history = monitor2.get_history()

        assert history["total_sessions"] == 1
        assert history["total_tokens"] == 10000
