"""Tests for the Loggable mixin."""

import logging

# from unittest.mock import patch, MagicMock # Using pytest-mock fixture instead
from unittest.mock import MagicMock  # Keep MagicMock

import pytest  # Import pytest for fixtures

from dana.common.mixins.loggable import Loggable


# pylint: disable=missing-function-docstring
# pylint: disable=missing-class-docstring
# pylint: disable=protected-access
class TestLoggable:
    """Test suite for the Loggable mixin."""

    @pytest.fixture
    def mock_logger(self, mocker):  # Use pytest-mock fixture 'mocker'
        """Fixture to mock DANA_LOGGER.getLogger and return a MagicMock."""
        mock = MagicMock()
        # Mock the getLogger method to return our mock logger instance
        mocker.patch("dana.common.utils.logging.dana_logger.DANA_LOGGER.getLogger", return_value=mock)
        # Mock getLoggerForClass as well, just in case
        mocker.patch("dana.common.utils.logging.dana_logger.DANA_LOGGER.getLoggerForClass", return_value=mock)
        return mock

    def test_custom_prefix(self, mock_logger):  # Inject the fixture
        """Test initialization with custom prefix."""
        # Define the behavior of the mocked getLogger when called with prefix
        # We need a way for the prefix passed to Loggable to affect the mock
        # Let's assume the prefix is set as an attribute on the mock logger instance
        # The actual Loggable.__instantiate_logger calls getLogger(..., prefix=prefix)
        # But our mocker patch just returns mock_logger regardless of args.
        # Let's check if the prefix is passed to getLogger instead.

        # We need to capture the arguments passed to getLogger
        # Let's adjust the fixture or test setup.
        pass  # Placeholder - Need to rethink how to test prefix passing

    def test_custom_level(self, mock_logger):  # Inject the fixture
        """Test initialization with custom logging level."""
        # With DANA_LOGGER already configured, Loggable should not call configure()
        # Instead, it should rely on the global configuration
        Loggable(level=logging.DEBUG)

        # configure() should not be called since DANA_LOGGER is already configured
        mock_logger.configure.assert_not_called()

        # But if level is explicitly provided, setLevel should be called
        mock_logger.setLevel.assert_called_once_with(logging.DEBUG)

    def test_log_data_enabled(self, mock_logger):  # Inject the fixture
        """Test initialization with log_data enabled."""
        # Note: log_data parameter is now deprecated and ignored
        Loggable(log_data=True)

        # configure() should not be called since DANA_LOGGER is already configured
        mock_logger.configure.assert_not_called()

        # No special handling for log_data in new implementation
        # It's accepted for backward compatibility but ignored

    def test_logging_methods(self, mock_logger):  # Inject the fixture
        """Test all logging methods."""
        obj = Loggable()  # With DANA_LOGGER configured, this won't call configure()
        message = "test message"
        context = {"key": "value"}

        # configure() should not be called since DANA_LOGGER is already configured
        mock_logger.configure.assert_not_called()

        # But the logging methods should still work
        obj.debug(message, **context)
        mock_logger.debug.assert_called_once_with(message, **context)

        obj.info(message, **context)
        mock_logger.info.assert_called_once_with(message, **context)

        obj.warning(message, **context)
        mock_logger.warning.assert_called_once_with(message, **context)

        obj.error(message, **context)
        mock_logger.error.assert_called_once_with(message, **context)
