"""Tests for application controller and command registration."""

from __future__ import annotations

from unittest.mock import patch

import pytest

from pytola_sim.lscsim.core.application_controller import ApplicationController
from pytola_sim.lscsim.utils.logger import get_logger

logger = get_logger(__name__)


class TestApplicationController:
    """Tests for ApplicationController."""

    def test_controller_initialization(self) -> None:
        """Test application controller initialization."""
        with patch("pytola_sim.lscsim.core.application_controller.DatabaseService"):
            controller = ApplicationController()

            # Test that controller is properly initialized
            assert controller is not None
            assert hasattr(controller, "_components")
            assert hasattr(controller, "_commands")

    def test_component_registration(self) -> None:
        """Test that components are registered correctly."""
        with patch("pytola_sim.lscsim.core.application_controller.DatabaseService"):
            controller = ApplicationController()

            # Check that components are registered
            component_ids = controller.get_component_ids()
            expected_components = [
                "FileModel",
                "Modeling",
                "Analysis",
                "ProductDatabase",
                "SimulationDatabase",
                "Settings",
                "Help",
            ]

            for component_id in expected_components:
                assert component_id in component_ids, f"Component {component_id} not registered"

            # Verify total component count
            assert len(component_ids) >= 7, f"Expected at least 7 components, got {len(component_ids)}"

    def test_command_registration(self) -> None:
        """Test that commands are registered correctly."""
        with patch("pytola_sim.lscsim.core.application_controller.DatabaseService"):
            controller = ApplicationController()

            # Get all registered commands
            commands = controller.get_all_registered_commands()

            # Test file commands
            file_commands = [
                "File.NewProject",
                "File.OpenProject",
                "File.SaveProject",
                "File.ImportCoordinates",
            ]

            for cmd in file_commands:
                assert cmd in commands, f"Command {cmd} not registered"
                component = controller.get_component_for_command(cmd)
                assert component is not None
                assert component.get_id() == "FileModel"

            # Test modeling commands
            modeling_commands = ["Modeling.CreateGeometry", "Modeling.GenerateMesh"]

            for cmd in modeling_commands:
                assert cmd in commands, f"Command {cmd} not registered"
                component = controller.get_component_for_command(cmd)
                assert component is not None
                assert component.get_id() == "Modeling"

            # Test analysis commands
            analysis_commands = ["Analysis.StartCalculation", "Analysis.GetResults"]

            for cmd in analysis_commands:
                assert cmd in commands, f"Command {cmd} not registered"
                component = controller.get_component_for_command(cmd)
                assert component is not None
                assert component.get_id() == "Analysis"

            # Verify total command count
            assert len(commands) >= 20, f"Expected at least 20 commands, got {len(commands)}"

    def test_command_execution_success(self) -> None:
        """Test successful command execution."""
        with patch("pytola_sim.lscsim.core.application_controller.DatabaseService"):
            controller = ApplicationController()

            # Test a simple command that should succeed
            result = controller.execute_command("File.NewProject", {"name": "Test Project"})
            # Since this is a mock scenario, we expect it to return False (unknown command)
            # But the important thing is that it doesn't crash
            assert isinstance(result, bool)

    def test_unknown_command_handling(self) -> None:
        """Test handling of unknown commands."""
        with patch("pytola_sim.lscsim.core.application_controller.DatabaseService"):
            controller = ApplicationController()

            # Test unknown command
            result = controller.execute_command("Unknown.Command")
            assert result is False

            # Test another unknown command
            result = controller.execute_command("NonExistent.Feature")
            assert result is False

    def test_component_retrieval(self) -> None:
        """Test component retrieval by ID."""
        with patch("pytola_sim.lscsim.core.application_controller.DatabaseService"):
            controller = ApplicationController()

            # Test getting existing components
            file_model = controller.get_component("FileModel")
            assert file_model is not None
            assert file_model.get_id() == "FileModel"

            modeling = controller.get_component("Modeling")
            assert modeling is not None
            assert modeling.get_id() == "Modeling"

            # Test getting non-existent component
            nonexistent = controller.get_component("NonExistentComponent")
            assert nonexistent is None

    def test_interface_retrieval(self) -> None:
        """Test interface retrieval."""
        with patch("pytola_sim.lscsim.core.application_controller.DatabaseService"):
            controller = ApplicationController()

            # Test getting file model interface
            file_interface = controller.get_interface_ptr("IFileModelCommands")
            assert file_interface is not None

            # Test getting modeling interface
            modeling_interface = controller.get_interface_ptr("IModelingCommands")
            assert modeling_interface is not None

            # Test getting non-existent interface
            nonexistent_interface = controller.get_interface_ptr("INonExistentInterface")
            assert nonexistent_interface is None

    def test_shutdown_process(self) -> None:
        """Test controller shutdown process."""
        with patch("pytola_sim.lscsim.core.application_controller.DatabaseService"):
            controller = ApplicationController()

            # Test shutdown without complex mocking (just test it doesn't crash)
            controller.shutdown()

            # The test passes if no exception is raised


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
