# [DEF:tests.test_logger:Module]
# @TIER: STANDARD
# @SEMANTICS: logging, tests, belief_state
# @PURPOSE: Unit tests for the custom logger formatters and configuration context manager.
# @LAYER: Logging (Tests)
# @RELATION: VERIFIES -> src/core/logger.py
# @INVARIANT: All required log statements must correctly check the threshold.

import pytest
from src.core.logger import (
    belief_scope,
    logger,
    configure_logger,
    get_task_log_level,
    should_log_task_level
)
from src.core.config_models import LoggingConfig


# [DEF:test_belief_scope_logs_entry_action_exit_at_debug:Function]
# @PURPOSE: Test that belief_scope generates [ID][Entry], [ID][Action], and [ID][Exit] logs at DEBUG level.
# @PRE: belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
# @POST: Logs are verified to contain Entry, Action, and Exit tags at DEBUG level.
def test_belief_scope_logs_entry_action_exit_at_debug(caplog):
    """Test that belief_scope generates [ID][Entry], [ID][Action], and [ID][Exit] logs at DEBUG level."""
    # Configure logger to DEBUG level
    config = LoggingConfig(
        level="DEBUG",
        task_log_level="DEBUG",
        enable_belief_state=True
    )
    configure_logger(config)
    
    caplog.set_level("DEBUG")

    with belief_scope("TestFunction"):
        logger.info("Doing something important")

    # Check that the logs contain the expected patterns
    log_messages = [record.message for record in caplog.records]

    assert any("[TestFunction][Entry]" in msg for msg in log_messages), "Entry log not found"
    assert any("[TestFunction][Action] Doing something important" in msg for msg in log_messages), "Action log not found"
    assert any("[TestFunction][Exit]" in msg for msg in log_messages), "Exit log not found"
    
    # Reset to INFO
    config = LoggingConfig(level="INFO", task_log_level="INFO", enable_belief_state=True)
    configure_logger(config)
# [/DEF:test_belief_scope_logs_entry_action_exit_at_debug:Function]


# [DEF:test_belief_scope_error_handling:Function]
# @PURPOSE: Test that belief_scope logs Coherence:Failed on exception.
# @PRE: belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
# @POST: Logs are verified to contain Coherence:Failed tag.
def test_belief_scope_error_handling(caplog):
    """Test that belief_scope logs Coherence:Failed on exception."""
    # Configure logger to DEBUG level
    config = LoggingConfig(
        level="DEBUG",
        task_log_level="DEBUG",
        enable_belief_state=True
    )
    configure_logger(config)
    
    caplog.set_level("DEBUG")

    with pytest.raises(ValueError):
        with belief_scope("FailingFunction"):
            raise ValueError("Something went wrong")

    log_messages = [record.message for record in caplog.records]

    assert any("[FailingFunction][Entry]" in msg for msg in log_messages), f"Entry log not found. Logs: {log_messages}"
    assert any("[FailingFunction][COHERENCE:FAILED]" in msg for msg in log_messages), f"Failed coherence log not found. Logs: {log_messages}"
    # Exit should not be logged on failure
    
    # Reset to INFO
    config = LoggingConfig(level="INFO", task_log_level="INFO", enable_belief_state=True)
    configure_logger(config)
# [/DEF:test_belief_scope_error_handling:Function]


# [DEF:test_belief_scope_success_coherence:Function]
# @PURPOSE: Test that belief_scope logs Coherence:OK on success.
# @PRE: belief_scope is available. caplog fixture is used. Logger configured to DEBUG.
# @POST: Logs are verified to contain Coherence:OK tag.
def test_belief_scope_success_coherence(caplog):
    """Test that belief_scope logs Coherence:OK on success."""
    # Configure logger to DEBUG level
    config = LoggingConfig(
        level="DEBUG",
        task_log_level="DEBUG",
        enable_belief_state=True
    )
    configure_logger(config)
    
    caplog.set_level("DEBUG")

    with belief_scope("SuccessFunction"):
        pass

    log_messages = [record.message for record in caplog.records]

    assert any("[SuccessFunction][COHERENCE:OK]" in msg for msg in log_messages), f"Success coherence log not found. Logs: {log_messages}"
    
    # Reset to INFO
    config = LoggingConfig(level="INFO", task_log_level="INFO", enable_belief_state=True)
    configure_logger(config)
# [/DEF:test_belief_scope_success_coherence:Function]


# [DEF:test_belief_scope_not_visible_at_info:Function]
# @PURPOSE: Test that belief_scope Entry/Exit/Coherence logs are NOT visible at INFO level.
# @PRE: belief_scope is available. caplog fixture is used.
# @POST: Entry/Exit/Coherence logs are not captured at INFO level.
def test_belief_scope_not_visible_at_info(caplog):
    """Test that belief_scope Entry/Exit/Coherence logs are NOT visible at INFO level."""
    caplog.set_level("INFO")

    with belief_scope("InfoLevelFunction"):
        logger.info("Doing something important")

    log_messages = [record.message for record in caplog.records]

    # Action log should be visible
    assert any("[InfoLevelFunction][Action] Doing something important" in msg for msg in log_messages), "Action log not found"
    # Entry/Exit/Coherence should NOT be visible at INFO level
    assert not any("[InfoLevelFunction][Entry]" in msg for msg in log_messages), "Entry log should not be visible at INFO"
    assert not any("[InfoLevelFunction][Exit]" in msg for msg in log_messages), "Exit log should not be visible at INFO"
    assert not any("[InfoLevelFunction][Coherence:OK]" in msg for msg in log_messages), "Coherence log should not be visible at INFO"
# [/DEF:test_belief_scope_not_visible_at_info:Function]


# [DEF:test_task_log_level_default:Function]
# @PURPOSE: Test that default task log level is INFO.
# @PRE: None.
# @POST: Default level is INFO.
def test_task_log_level_default():
    """Test that default task log level is INFO."""
    level = get_task_log_level()
    assert level == "INFO"
# [/DEF:test_task_log_level_default:Function]


# [DEF:test_should_log_task_level:Function]
# @PURPOSE: Test that should_log_task_level correctly filters log levels.
# @PRE: None.
# @POST: Filtering works correctly for all level combinations.
def test_should_log_task_level():
    """Test that should_log_task_level correctly filters log levels."""
    # Default level is INFO
    assert should_log_task_level("ERROR") is True, "ERROR should be logged at INFO threshold"
    assert should_log_task_level("WARNING") is True, "WARNING should be logged at INFO threshold"
    assert should_log_task_level("INFO") is True, "INFO should be logged at INFO threshold"
    assert should_log_task_level("DEBUG") is False, "DEBUG should NOT be logged at INFO threshold"
# [/DEF:test_should_log_task_level:Function]


# [DEF:test_configure_logger_task_log_level:Function]
# @PURPOSE: Test that configure_logger updates task_log_level.
# @PRE: LoggingConfig is available.
# @POST: task_log_level is updated correctly.
def test_configure_logger_task_log_level():
    """Test that configure_logger updates task_log_level."""
    config = LoggingConfig(
        level="DEBUG",
        task_log_level="DEBUG",
        enable_belief_state=True
    )
    configure_logger(config)
    
    assert get_task_log_level() == "DEBUG", "task_log_level should be DEBUG"
    assert should_log_task_level("DEBUG") is True, "DEBUG should be logged at DEBUG threshold"
    
    # Reset to INFO
    config = LoggingConfig(
        level="INFO",
        task_log_level="INFO",
        enable_belief_state=True
    )
    configure_logger(config)
    assert get_task_log_level() == "INFO", "task_log_level should be reset to INFO"
# [/DEF:test_configure_logger_task_log_level:Function]


# [DEF:test_enable_belief_state_flag:Function]
# @PURPOSE: Test that enable_belief_state flag controls belief_scope logging.
# @PRE: LoggingConfig is available. caplog fixture is used.
# @POST: belief_scope logs are controlled by the flag.
def test_enable_belief_state_flag(caplog):
    """Test that enable_belief_state flag controls belief_scope logging."""
    # Disable belief state
    config = LoggingConfig(
        level="DEBUG",
        task_log_level="DEBUG",
        enable_belief_state=False
    )
    configure_logger(config)
    
    caplog.set_level("DEBUG")
    
    with belief_scope("DisabledFunction"):
        logger.info("Doing something")
    
    log_messages = [record.message for record in caplog.records]
    
    # Entry and Exit should NOT be logged when disabled
    assert not any("[DisabledFunction][Entry]" in msg for msg in log_messages), "Entry should not be logged when disabled"
    assert not any("[DisabledFunction][Exit]" in msg for msg in log_messages), "Exit should not be logged when disabled"
    # Coherence:OK should still be logged (internal tracking)
    assert any("[DisabledFunction][COHERENCE:OK]" in msg for msg in log_messages), "Coherence should still be logged"
    
    # Re-enable for other tests
    config = LoggingConfig(
        level="DEBUG",
        task_log_level="DEBUG",
        enable_belief_state=True
    )
    configure_logger(config)
# [/DEF:test_enable_belief_state_flag:Function]
# [/DEF:tests.test_logger:Module]