"""
Tests for web/models/database.py

Tests cover:
- get_db_connection (deprecated)
- calculate_duration function
- get_logs_for_research function
- get_total_logs_for_research function
"""

import pytest
from unittest.mock import Mock, patch
from datetime import datetime, timezone, timedelta


class TestGetDbConnection:
    """Tests for deprecated get_db_connection function."""

    def test_get_db_connection_raises_runtime_error(self):
        """Test that get_db_connection raises RuntimeError."""
        from local_deep_research.web.models.database import get_db_connection

        with pytest.raises(RuntimeError) as exc_info:
            get_db_connection()

        assert "Shared database access is deprecated" in str(exc_info.value)


class TestCalculateDuration:
    """Tests for calculate_duration function."""

    def test_calculate_duration_iso_format(self):
        """Test duration calculation with ISO format timestamps."""
        from local_deep_research.web.models.database import calculate_duration

        created_at = "2025-01-01T10:00:00+00:00"
        completed_at = "2025-01-01T10:05:00+00:00"

        result = calculate_duration(created_at, completed_at)

        assert result == 300  # 5 minutes = 300 seconds

    def test_calculate_duration_with_microseconds(self):
        """Test duration calculation with microseconds in ISO format."""
        from local_deep_research.web.models.database import calculate_duration

        # Use ISO format with timezone for proper parsing
        created_at = "2025-01-01T10:00:00.123456+00:00"
        completed_at = "2025-01-01T10:01:00.654321+00:00"

        result = calculate_duration(created_at, completed_at)

        # Should be approximately 60 seconds
        assert result == 60 or result == 61

    def test_calculate_duration_without_completed_at(self):
        """Test duration calculation without completed_at uses current time."""
        from local_deep_research.web.models.database import calculate_duration

        # Create a recent timestamp
        now = datetime.now(timezone.utc)
        created_at = (now - timedelta(seconds=120)).isoformat()

        result = calculate_duration(created_at)

        # Should be approximately 120 seconds (with some tolerance)
        assert result is not None
        assert 115 <= result <= 130

    def test_calculate_duration_none_created_at(self):
        """Test duration calculation with None created_at."""
        from local_deep_research.web.models.database import calculate_duration

        result = calculate_duration(None)

        assert result is None

    def test_calculate_duration_empty_created_at(self):
        """Test duration calculation with empty created_at."""
        from local_deep_research.web.models.database import calculate_duration

        result = calculate_duration("")

        assert result is None

    def test_calculate_duration_space_separated_format(self):
        """Test duration with space-separated timestamp format with timezone."""
        from local_deep_research.web.models.database import calculate_duration

        # Use format with timezone suffix for proper handling
        created_at = "2025-01-01 10:00:00+00:00"
        completed_at = "2025-01-01 10:10:00+00:00"

        result = calculate_duration(created_at, completed_at)

        assert result == 600  # 10 minutes = 600 seconds

    def test_calculate_duration_replaces_space_with_t(self):
        """Test that space is replaced with T for parsing."""
        from local_deep_research.web.models.database import calculate_duration

        # This format should fall back to replacing space with T
        created_at = "2025-01-01 10:00:00+00:00"
        completed_at = "2025-01-01 10:02:00+00:00"

        result = calculate_duration(created_at, completed_at)

        assert result == 120  # 2 minutes


class TestGetLogsForResearch:
    """Tests for get_logs_for_research function."""

    def test_get_logs_success(self):
        """Test successful log retrieval."""
        mock_session = Mock()
        mock_log = Mock()
        mock_log.timestamp = "2025-01-01T10:00:00"
        mock_log.message = "Test log message"
        mock_log.level = "INFO"
        mock_log.module = "test_module"
        mock_log.line_no = 42

        mock_query = Mock()
        mock_query.filter.return_value = mock_query
        mock_query.order_by.return_value = mock_query
        mock_query.all.return_value = [mock_log]
        mock_session.query.return_value = mock_query

        with patch(
            "local_deep_research.web.models.database.get_user_db_session"
        ) as mock_get_session:
            mock_get_session.return_value.__enter__ = Mock(
                return_value=mock_session
            )
            mock_get_session.return_value.__exit__ = Mock(return_value=False)

            from local_deep_research.web.models.database import (
                get_logs_for_research,
            )

            result = get_logs_for_research("test-research-id")

            assert len(result) == 1
            assert result[0]["message"] == "Test log message"
            assert result[0]["type"] == "INFO"
            assert result[0]["module"] == "test_module"
            assert result[0]["line_no"] == 42

    def test_get_logs_empty(self):
        """Test log retrieval when no logs exist."""
        mock_session = Mock()
        mock_query = Mock()
        mock_query.filter.return_value = mock_query
        mock_query.order_by.return_value = mock_query
        mock_query.all.return_value = []
        mock_session.query.return_value = mock_query

        with patch(
            "local_deep_research.web.models.database.get_user_db_session"
        ) as mock_get_session:
            mock_get_session.return_value.__enter__ = Mock(
                return_value=mock_session
            )
            mock_get_session.return_value.__exit__ = Mock(return_value=False)

            from local_deep_research.web.models.database import (
                get_logs_for_research,
            )

            result = get_logs_for_research("nonexistent-id")

            assert result == []

    def test_get_logs_error_returns_empty(self):
        """Test that errors return empty list."""
        with patch(
            "local_deep_research.web.models.database.get_user_db_session"
        ) as mock_get_session:
            mock_get_session.return_value.__enter__ = Mock(
                side_effect=Exception("Database error")
            )

            from local_deep_research.web.models.database import (
                get_logs_for_research,
            )

            result = get_logs_for_research("test-id")

            assert result == []


class TestGetTotalLogsForResearch:
    """Tests for get_total_logs_for_research function."""

    def test_get_total_logs_success(self):
        """Test successful total log count."""
        mock_session = Mock()
        mock_query = Mock()
        mock_query.filter.return_value = mock_query
        mock_query.count.return_value = 42
        mock_session.query.return_value = mock_query

        with patch(
            "local_deep_research.web.models.database.get_user_db_session"
        ) as mock_get_session:
            mock_get_session.return_value.__enter__ = Mock(
                return_value=mock_session
            )
            mock_get_session.return_value.__exit__ = Mock(return_value=False)

            from local_deep_research.web.models.database import (
                get_total_logs_for_research,
            )

            result = get_total_logs_for_research("test-research-id")

            assert result == 42

    def test_get_total_logs_zero(self):
        """Test total log count when no logs exist."""
        mock_session = Mock()
        mock_query = Mock()
        mock_query.filter.return_value = mock_query
        mock_query.count.return_value = 0
        mock_session.query.return_value = mock_query

        with patch(
            "local_deep_research.web.models.database.get_user_db_session"
        ) as mock_get_session:
            mock_get_session.return_value.__enter__ = Mock(
                return_value=mock_session
            )
            mock_get_session.return_value.__exit__ = Mock(return_value=False)

            from local_deep_research.web.models.database import (
                get_total_logs_for_research,
            )

            result = get_total_logs_for_research("nonexistent-id")

            assert result == 0


class TestDurationEdgeCases:
    """Edge case tests for calculate_duration."""

    def test_negative_duration(self):
        """Test when completed_at is before created_at."""
        from local_deep_research.web.models.database import calculate_duration

        created_at = "2025-01-01T10:10:00+00:00"
        completed_at = "2025-01-01T10:00:00+00:00"

        result = calculate_duration(created_at, completed_at)

        # Should return negative value
        assert result == -600  # -10 minutes

    def test_very_long_duration(self):
        """Test with very long duration."""
        from local_deep_research.web.models.database import calculate_duration

        created_at = "2025-01-01T00:00:00+00:00"
        completed_at = "2025-01-02T00:00:00+00:00"

        result = calculate_duration(created_at, completed_at)

        assert result == 86400  # 24 hours = 86400 seconds

    def test_zero_duration(self):
        """Test with same timestamps."""
        from local_deep_research.web.models.database import calculate_duration

        created_at = "2025-01-01T10:00:00+00:00"
        completed_at = "2025-01-01T10:00:00+00:00"

        result = calculate_duration(created_at, completed_at)

        assert result == 0
