"""
Tests for the IntentRouter class.
"""
import unittest
from unittest.mock import MagicMock, patch
from metis_agent.core.intent_router import IntentRouter


class TestIntentRouter(unittest.TestCase):
    """Test cases for the IntentRouter class."""
    
    def setUp(self):
        """Set up test fixtures."""
        # Create a mock LLM for testing
        self.mock_llm = MagicMock()
        
        # Patch the get_llm function to return our mock
        self.patcher = patch('metis_agent.core.llm_interface.get_llm', return_value=self.mock_llm)
        self.patcher.start()
        
        # Create an IntentRouter instance
        self.intent_router = IntentRouter()
        
    def tearDown(self):
        """Tear down test fixtures."""
        self.patcher.stop()
        
    def test_simple_greeting_detection(self):
        """Test detection of simple greetings."""
        greetings = [
            "hello",
            "hi there",
            "hey",
            "good morning",
            "how are you"
        ]
        
        for greeting in greetings:
            self.assertTrue(
                self.intent_router._is_simple_greeting(greeting),
                f"Failed to detect greeting: {greeting}"
            )
            
    def test_non_greeting_detection(self):
        """Test detection of non-greetings."""
        non_greetings = [
            "write a Python function to calculate Fibonacci numbers",
            "what is the capital of France?",
            "create a blog post about AI ethics",
            "search for information about quantum computing"
        ]
        
        for text in non_greetings:
            self.assertFalse(
                self.intent_router._is_simple_greeting(text),
                f"Incorrectly detected as greeting: {text}"
            )
            
    def test_simple_question_detection(self):
        """Test detection of simple questions."""
        questions = [
            "what is machine learning?",
            "how does quantum computing work?",
            "where is the Eiffel Tower?",
            "when was the internet invented?"
        ]
        
        for question in questions:
            self.assertTrue(
                self.intent_router._is_simple_question(question),
                f"Failed to detect question: {question}"
            )
            
    def test_complex_task_detection(self):
        """Test detection of complex tasks."""
        tasks = [
            "write a Python function to calculate Fibonacci numbers",
            "create a blog post about AI ethics",
            "generate a marketing plan for a new product",
            "implement a binary search algorithm in Java"
        ]
        
        for task in tasks:
            self.assertTrue(
                self.intent_router._is_complex_task(task),
                f"Failed to detect task: {task}"
            )
            
    def test_classify_greeting_as_question(self):
        """Test classification of greetings as questions."""
        greetings = [
            "hello",
            "hi there",
            "hey",
            "good morning",
            "how are you"
        ]
        
        for greeting in greetings:
            self.assertEqual(
                "question",
                self.intent_router.classify(greeting),
                f"Failed to classify greeting as question: {greeting}"
            )
            
    def test_classify_question_as_question(self):
        """Test classification of questions as questions."""
        questions = [
            "what is machine learning?",
            "how does quantum computing work?",
            "where is the Eiffel Tower?",
            "when was the internet invented?"
        ]
        
        for question in questions:
            self.assertEqual(
                "question",
                self.intent_router.classify(question),
                f"Failed to classify question as question: {question}"
            )
            
    def test_classify_task_as_task(self):
        """Test classification of tasks as tasks."""
        tasks = [
            "write a Python function to calculate Fibonacci numbers",
            "create a blog post about AI ethics",
            "generate a marketing plan for a new product",
            "implement a binary search algorithm in Java"
        ]
        
        for task in tasks:
            self.assertEqual(
                "task",
                self.intent_router.classify(task),
                f"Failed to classify task as task: {task}"
            )
            
    def test_llm_classification(self):
        """Test LLM-based classification."""
        # Set up the mock LLM to return "question"
        self.mock_llm.complete.return_value = "question"
        
        # Test with an ambiguous query
        query = "I need information about quantum computing"
        
        # Ensure the ambiguous query is not caught by rule-based methods
        self.assertFalse(self.intent_router._is_simple_greeting(query))
        self.assertFalse(self.intent_router._is_simple_question(query))
        self.assertFalse(self.intent_router._is_complex_task(query))
        
        # Test the classification
        result = self.intent_router.classify(query)
        
        # Verify the result
        self.assertEqual("question", result)
        
        # Verify the LLM was called
        self.mock_llm.complete.assert_called_once()
        
    def test_fallback_classification(self):
        """Test fallback classification when LLM fails."""
        # Set up the mock LLM to raise an exception
        self.mock_llm.complete.side_effect = Exception("LLM error")
        
        # Test with an ambiguous query
        query = "I need information about quantum computing"
        
        # Test the classification
        result = self.intent_router.classify(query)
        
        # Verify the result is either "question" or "task"
        self.assertIn(result, ["question", "task"])
        
        # Verify the LLM was called
        self.mock_llm.complete.assert_called_once()


if __name__ == '__main__':
    unittest.main()