"""
Utility class for getting routes from a FastAPI app.
"""

from typing import Any, Dict, List, Optional

from starlette.routing import BaseRoute

from litellm._logging import verbose_logger


class GetRoutes:
    @staticmethod
    def get_app_routes(
        route: BaseRoute,
        endpoint_route: Any,
    ) -> List[Dict[str, Any]]:
        """
        Get routes for a regular route.
        """
        routes: List[Dict[str, Any]] = []
        route_info = {
            "path": getattr(route, "path", None),
            "methods": getattr(route, "methods", None),
            "name": getattr(route, "name", None),
            "endpoint": (
                endpoint_route.__name__
                if getattr(route, "endpoint", None)
                else None
            ),
        }
        routes.append(route_info)
        return routes
    
    @staticmethod
    def get_routes_for_mounted_app(
        route: BaseRoute,
    ) -> List[Dict[str, Any]]:
        """
        Get routes for a mounted sub-application.
        """
        routes: List[Dict[str, Any]] = []
        mount_path = getattr(route, 'path', '')
        sub_app = getattr(route, 'app', None)
        if sub_app and hasattr(sub_app, 'routes'):
            for sub_route in sub_app.routes:
                # Get endpoint - either from endpoint attribute or app attribute
                endpoint_func = getattr(sub_route, "endpoint", None) or getattr(sub_route, "app", None)
                
                if endpoint_func is not None:
                    sub_route_path = getattr(sub_route, "path", "")
                    full_path = mount_path.rstrip('/') + sub_route_path
                    
                    route_info = {
                        "path": full_path,
                        "methods": getattr(sub_route, "methods", ["GET", "POST"]),
                        "name": getattr(sub_route, "name", None),
                        "endpoint": GetRoutes._safe_get_endpoint_name(endpoint_func),
                        "mounted_app": True,
                    }
                    routes.append(route_info)
        return routes
    

    @staticmethod
    def _safe_get_endpoint_name(endpoint_function: Any) -> Optional[str]:
        """
        Safely get the name of the endpoint function.
        """
        try:
            if hasattr(endpoint_function, '__name__'):
                return getattr(endpoint_function, '__name__')
            elif hasattr(endpoint_function, '__class__') and hasattr(endpoint_function.__class__, '__name__'):
                return getattr(endpoint_function.__class__, '__name__')
            else:
                return None
        except Exception:
            verbose_logger.exception(f"Error getting endpoint name for route: {endpoint_function}")
            return None