"""
Test script to validate custom context window size setting.

This script tests if we can set a custom context window size for different model providers.
It simulates the fix for issue #241: https://github.com/LearningCircuit/local-deep-research/issues/241
"""

import sys
from pathlib import Path
from typing import Any, Dict, Optional

from loguru import logger

# Add the src directory to the path before importing project modules
src_path = str(Path(__file__).parent.parent.parent / "src")
if src_path not in sys.path:
    sys.path.insert(0, src_path)


def patch_db_setting():
    """
    Patch the settings retrieval to override certain settings.
    This simulates what would happen if we added a context_window_size setting.
    """
    # Import here to avoid module level import issues
    # Note: We don't call the original function to avoid thread context issues
    settings_override = {
        "llm.context_window_size": 8192,  # Custom context window size setting
        "llm.max_tokens": 30000,  # Add max_tokens to avoid thread context error
    }

    def patched_get_setting(
        key: str,
        default=None,
        username=None,
        settings_snapshot=None,
    ) -> Any:
        """Override specific settings for testing.

        Signature must match the real get_setting_from_snapshot() to avoid
        TypeError when other tests run on the same pytest-xdist worker.
        """
        if key in settings_override:
            return settings_override[key]
        # Return default value instead of calling original to avoid thread context issues
        return (
            default if default is not None else settings_override.get(key, None)
        )

    # Apply the patch
    import local_deep_research.config.thread_settings

    local_deep_research.config.thread_settings.get_setting_from_snapshot = (
        patched_get_setting
    )

    # Also patch the llm_config module
    import local_deep_research.config.llm_config

    local_deep_research.config.llm_config.get_setting_from_snapshot = (
        patched_get_setting
    )

    return patched_get_setting


def modify_llm_creation(
    provider: str, model_name: Optional[str] = None
) -> Dict:
    """
    Simulate creating an LLM with a custom context window size setting.

    Args:
        provider: The LLM provider to use
        model_name: Optional model name to use

    Returns:
        Dict containing configuration used
    """
    # Use hardcoded values for testing since we don't have a settings context
    # The patch_db_setting() function will override these if needed
    context_window_size = 8192  # Custom context window size for testing
    max_tokens = 30000  # Default max_tokens for testing

    logger.info(f"Provider: {provider}")
    logger.info(f"Context window size from settings: {context_window_size}")
    logger.info(f"Current max_tokens setting: {max_tokens}")

    # Calculate new max_tokens based on context window size
    # In a real implementation, this would ensure max_tokens doesn't exceed the model's context window
    new_max_tokens = min(max_tokens, int(context_window_size * 0.8))
    logger.info(f"Adjusted max_tokens would be: {new_max_tokens}")

    # For certain providers, this is especially important
    if provider in ["llamacpp", "lmstudio", "ollama"]:
        logger.info(
            f"Provider {provider} would particularly benefit from custom context size"
        )

    return {
        "provider": provider,
        "model_name": model_name,
        "context_window_size": context_window_size,
        "original_max_tokens": max_tokens,
        "adjusted_max_tokens": new_max_tokens,
    }


def test_custom_context_size():
    """
    Test custom context window size for different providers.
    """
    # Import here to avoid module level import issues
    from local_deep_research.config.llm_config import get_available_providers
    import local_deep_research.config.thread_settings
    import local_deep_research.config.llm_config

    # Save originals so we can restore after test
    orig_thread_settings = (
        local_deep_research.config.thread_settings.get_setting_from_snapshot
    )
    orig_llm_config = (
        local_deep_research.config.llm_config.get_setting_from_snapshot
    )

    try:
        # Apply the patch to simulate new setting
        patch_db_setting()

        # Get available providers
        providers = get_available_providers()
        logger.info(f"Available providers: {list(providers.keys())}")

        # Test each provider
        results = {}
        for provider in providers:
            logger.info(f"\nTesting provider: {provider}")
            try:
                result = modify_llm_creation(provider)
                results[provider] = result
            except Exception as e:
                logger.exception(f"Error testing provider {provider}")
                results[provider] = {"error": str(e)}

        # Show summary
        logger.info("\n\n=== TEST RESULTS ===")
        for provider, result in results.items():
            test_succeeded = "error" not in result
            status = "✓" if "error" not in result else "✗"
            logger.info(f"{status} {provider}: {result}")
            assert test_succeeded
    finally:
        # Restore original functions to prevent pollution of other tests
        local_deep_research.config.thread_settings.get_setting_from_snapshot = (
            orig_thread_settings
        )
        local_deep_research.config.llm_config.get_setting_from_snapshot = (
            orig_llm_config
        )


if __name__ == "__main__":
    logger.info("Testing custom context window size functionality")
    test_custom_context_size()
