from django.apps import apps
from django.test import TestCase

from routing.app_settings import corptools_active, drifters_active


class AppSettingsTest(TestCase):
    """Test the app_settings functions for detecting optional dependencies"""

    def test_corptools_active_returns_bool(self) -> None:
        """Test that corptools_active returns a boolean"""
        result = corptools_active()
        self.assertIsInstance(result, bool)

    def test_drifters_active_returns_bool(self) -> None:
        """Test that drifters_active returns a boolean"""
        result = drifters_active()
        self.assertIsInstance(result, bool)

    def test_corptools_active_detection(self) -> None:
        """Test that corptools_active correctly identifies if corptools is installed"""
        # Check if it matches actual installation status
        is_installed = apps.is_installed("corptools")
        self.assertEqual(corptools_active(), is_installed)

    def test_drifters_active_detection(self) -> None:
        """Test that drifters_active correctly identifies if drifters is installed"""
        # Check if it matches actual installation status
        is_installed = apps.is_installed("drifters")
        self.assertEqual(drifters_active(), is_installed)

    def test_apps_import_consistency(self) -> None:
        """Test that app detection is consistent with Django's apps registry"""
        # Both functions use apps.is_installed(), verify they're consistent
        corptools = corptools_active()
        is_corptools_installed = apps.is_installed("corptools")
        self.assertEqual(corptools, is_corptools_installed)

        drifters = drifters_active()
        is_drifters_installed = apps.is_installed("drifters")
        self.assertEqual(drifters, is_drifters_installed)

    def test_multiple_calls_consistent(self) -> None:
        """Test that multiple calls to the functions return consistent results"""
        # Call multiple times to ensure consistency
        corptools_results = [corptools_active(), corptools_active(), corptools_active()]
        drifters_results = [drifters_active(), drifters_active(), drifters_active()]

        # All results should be the same
        self.assertEqual(len(set(corptools_results)), 1)
        self.assertEqual(len(set(drifters_results)), 1)

    def test_app_settings_no_side_effects(self) -> None:
        """Test that app_settings functions have no side effects"""
        # Just verify they can be called without any errors
        try:
            corptools_active()
            drifters_active()
        except Exception as e:
            self.fail(f"App settings functions raised exception: {e}")

    def test_corptools_vs_drifters_independence(self) -> None:
        """Test that corptools and drifters detection are independent"""
        # They might both be installed, both not installed, or mixed
        corptools = corptools_active()
        drifters = drifters_active()

        # Just verify they're both boolean, no specific relationship required
        self.assertIsInstance(corptools, bool)
        self.assertIsInstance(drifters, bool)

    def test_function_behavior_without_dependencies(self) -> None:
        """Test that functions handle cases where apps might not be installed"""
        # These functions should never raise exceptions
        try:
            result1 = corptools_active()
            result2 = drifters_active()
            self.assertIsNotNone(result1)
            self.assertIsNotNone(result2)
        except Exception as e:
            self.fail(f"Functions should handle missing apps gracefully: {e}")
