# Path: rollbar/contrib/fastapi/middleware.py
# class ReporterMiddleware(StarletteReporterMiddleware):
#     ...
# 
# Path: rollbar/contrib/starlette/middleware.py
# class ReporterMiddleware(ASGIReporterMiddleware):
#     async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
#         try:
#             store_current_request(scope, receive)
#             await self.app(scope, receive, send)
#         except Exception:
#             if scope['type'] == 'http':
#                 request = Request(scope, receive)
# 
#                 # Consuming the request body in Starlette middleware is problematic.
#                 # See: https://github.com/encode/starlette/issues/495#issuecomment-494008175
#                 #
#                 # Uncomment lines below if you know the risks.
#                 #
#                 # Starlette requires the `python-multipart` package to parse the content
#                 # await request.body()
#                 # await request.form()
# 
#                 exc_info = sys.exc_info()
# 
#                 try:
#                     await try_report(exc_info, request)
#                 except RollbarAsyncError:
#                     log.warning(
#                         'Failed to report asynchronously. Trying to report synchronously.'
#                     )
#                     rollbar.report_exc_info(exc_info, request)
#             raise
# 
# Path: rollbar/contrib/asgi/middleware.py
# class ReporterMiddleware(IntegrationBase):
#     def __init__(self, app: ASGIApp) -> None:
#         super().__init__()
# 
#         self.app = app
# 
#     async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
#         try:
#             await self.app(scope, receive, send)
#         except Exception:
#             if scope['type'] == 'http':
#                 exc_info = sys.exc_info()
# 
#                 try:
#                     await try_report(exc_info)
#                 except RollbarAsyncError:
#                     log.warning(
#                         'Failed to report asynchronously. Trying to report synchronously.'
#                     )
#                     rollbar.report_exc_info(exc_info)
#             raise


import functools
import logging
import fastapi
from fastapi import APIRouter, FastAPI
from . import ReporterMiddleware as FastAPIReporterMiddleware
from rollbar.contrib.starlette import ReporterMiddleware as StarletteReporterMiddleware
from rollbar.contrib.asgi import ReporterMiddleware as ASGIReporterMiddleware


def get_installed_middlewares(app):
    candidates = (
        FastAPIReporterMiddleware,
        StarletteReporterMiddleware,
        ASGIReporterMiddleware,
    )

    middlewares = []

    if hasattr(app, 'user_middleware'):  # FastAPI v0.51.0+
        middlewares = [
            middleware.cls
            for middleware in app.user_middleware
            if middleware.cls in candidates
        ]
    elif hasattr(app, 'error_middleware'):
        middleware = app.error_middleware

        while hasattr(middleware, 'app'):
            if isinstance(middleware, candidates):
                middlewares.append(middleware)
            middleware = middleware.app

        middlewares = [middleware.__class__ for middleware in middlewares]

    return middlewares



# Path: rollbar/contrib/fastapi/middleware.py
# class ReporterMiddleware(StarletteReporterMiddleware):
#     ...
# 
# Path: rollbar/contrib/starlette/middleware.py
# class ReporterMiddleware(ASGIReporterMiddleware):
#     async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
#         try:
#             store_current_request(scope, receive)
#             await self.app(scope, receive, send)
#         except Exception:
#             if scope['type'] == 'http':
#                 request = Request(scope, receive)
# 
#                 # Consuming the request body in Starlette middleware is problematic.
#                 # See: https://github.com/encode/starlette/issues/495#issuecomment-494008175
#                 #
#                 # Uncomment lines below if you know the risks.
#                 #
#                 # Starlette requires the `python-multipart` package to parse the content
#                 # await request.body()
#                 # await request.form()
# 
#                 exc_info = sys.exc_info()
# 
#                 try:
#                     await try_report(exc_info, request)
#                 except RollbarAsyncError:
#                     log.warning(
#                         'Failed to report asynchronously. Trying to report synchronously.'
#                     )
#                     rollbar.report_exc_info(exc_info, request)
#             raise
# 
# Path: rollbar/contrib/asgi/middleware.py
# class ReporterMiddleware(IntegrationBase):
#     def __init__(self, app: ASGIApp) -> None:
#         super().__init__()
# 
#         self.app = app
# 
#     async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
#         try:
#             await self.app(scope, receive, send)
#         except Exception:
#             if scope['type'] == 'http':
#                 exc_info = sys.exc_info()
# 
#                 try:
#                     await try_report(exc_info)
#                 except RollbarAsyncError:
#                     log.warning(
#                         'Failed to report asynchronously. Trying to report synchronously.'
#                     )
#                     rollbar.report_exc_info(exc_info)
#             raise


# Path: rollbar/contrib/fastapi/utils.py
import functools
import logging
import fastapi
from fastapi import APIRouter, FastAPI
from . import ReporterMiddleware as FastAPIReporterMiddleware
from rollbar.contrib.starlette import ReporterMiddleware as StarletteReporterMiddleware
from rollbar.contrib.asgi import ReporterMiddleware as ASGIReporterMiddleware



def get_installed_middlewares(app):
    candidates = (
        FastAPIReporterMiddleware,
        StarletteReporterMiddleware,
        ASGIReporterMiddleware,
    )

    middlewares = []

    if hasattr(app, 'user_middleware'):  # FastAPI v0.51.0+
        middlewares = [
            middleware.cls
            for middleware in app.user_middleware
            if middleware.cls in candidates
        ]
    elif hasattr(app, 'error_middleware'):
        middleware = app.error_middleware

        while hasattr(middleware, 'app'):
            if isinstance(middleware, candidates):
                middlewares.append(middleware)
            middleware = middleware.app

        middlewares = [middleware.__class__ for middleware in middlewares]

    return middlewares



def has_bare_routing(app_or_router):