# Generated by oapi-gen 0.1.9. DO NOT EDIT.
# Source SHA256: 3bdca241e5ef74b0620c69faa4a6e49f171c0542f987ae89044b07b922113dc4
from __future__ import annotations

from functools import partial
from pathlib import Path
from typing import Annotated, Literal

from msgspec import Meta, json
from starlette.exceptions import HTTPException
from starlette.requests import Request
from starlette.responses import Response
from starlette.routing import Route, Router

from ._runtime import RequestError as _runtime_RequestError
from ._runtime import bearer_auth as _runtime_bearer_auth
from ._runtime import boolean as _runtime_boolean
from ._runtime import check_json_content_type as _runtime_check_json_content_type
from ._runtime import check_property_counts as _runtime_check_property_counts
from ._runtime import comma_values as _runtime_comma_values
from ._runtime import encode_header as _runtime_encode_header
from ._runtime import error_response as _runtime_error_response
from ._runtime import json_body as _runtime_json_body
from ._runtime import multipart_body as _runtime_multipart_body
from ._runtime import parameter as _runtime_parameter
from ._runtime import upload as _runtime_upload
from ._streams import EventField as _streams_EventField
from ._streams import StreamResponse as _streams_StreamResponse
from ._streams import encode_json_item as _streams_encode_json_item
from ._streams import encode_sse_item as _streams_encode_sse_item
from .contracts import DeviceSecurity
from .contracts import ExportCats as _contracts_ExportCats
from .contracts import ExportCatsNdjson as _contracts_ExportCatsNdjson
from .contracts import ExportCatsSequence as _contracts_ExportCatsSequence
from .contracts import Handlers, SecurityHandler, SecurityRejected
from .contracts import WatchCats as _contracts_WatchCats
from .models import Cat as _models_Cat

_encoder = json.Encoder()
_watch_cats_parameter_0 = str | None
json.Decoder(_watch_cats_parameter_0)
_watch_cats_200_event_fields = (
    _streams_EventField("data", True, json.Decoder(_models_Cat), json.Decoder(str), True, None),
    _streams_EventField(
        "event",
        True,
        json.Decoder(Literal["cat.updated"]),
        json.Decoder(Literal["cat.updated"]),
        False,
        None,
    ),
    _streams_EventField("id", False, json.Decoder(str), json.Decoder(str), False, None),
    _streams_EventField(
        "retry",
        False,
        json.Decoder(Annotated[int, Meta(ge=0)]),
        json.Decoder(Annotated[int, Meta(ge=0)]),
        False,
        None,
    ),
)
_export_cats_200_decoder = json.Decoder(_models_Cat)
_export_cats_ndjson_200_decoder = json.Decoder(_models_Cat)
_export_cats_sequence_200_decoder = json.Decoder(_models_Cat)


def create_router(
    handlers: Handlers, *, security: SecurityHandler, prefix: str = "", include_schema: bool = True
) -> Router:
    __oapi_handlers = handlers
    __oapi_security = security

    async def __oapi_endpoint_watch_cats(__oapi_http: Request) -> Response:
        __oapi_security_context: object | None = None
        __oapi_security_satisfied = False
        __oapi_security_0 = _runtime_bearer_auth(__oapi_http.headers.get("authorization"))
        if not __oapi_security_satisfied and __oapi_security_0 is not None:
            try:
                __oapi_alternative_context = None
                __oapi_alternative_context = await __oapi_security.handle_device(
                    __oapi_alternative_context,
                    "watchCats",
                    DeviceSecurity(
                        token=__oapi_security_0.credentials,
                        scopes=("cats:read",),
                    ),
                )
            except SecurityRejected:
                pass
            else:
                __oapi_security_context = __oapi_alternative_context
                __oapi_security_satisfied = True
        if not __oapi_security_satisfied:
            raise HTTPException(status_code=401, detail="security requirements are not satisfied")
        try:
            __oapi_parameter_0 = _runtime_parameter(
                __oapi_http.headers.get("Last-Event-ID"),
                _watch_cats_parameter_0,
                ("header", "Last-Event-ID"),
                required=False,
                default=None,
            )
        except _runtime_RequestError as __oapi_error:
            return _runtime_error_response(__oapi_error)
        __oapi_request = _contracts_WatchCats.Request(
            last_event_id=__oapi_parameter_0, security_context=__oapi_security_context
        )
        try:
            __oapi_result = await __oapi_handlers.cats.watch_cats(__oapi_request)
        except _contracts_WatchCats.Forbidden as __oapi_error:
            __oapi_result = __oapi_error
        else:
            if isinstance(__oapi_result, Exception):
                raise TypeError("watchCats error responses must be raised")
        if isinstance(__oapi_result, _contracts_WatchCats.Ok):
            return _streams_StreamResponse(
                __oapi_result.body,
                encode=partial(
                    _streams_encode_sse_item,
                    event_type=_contracts_WatchCats.Event,
                    fields=_watch_cats_200_event_fields,
                    checked=True,
                ),
                status_code=200,
                media_type="text/event-stream",
            )
        if isinstance(__oapi_result, _contracts_WatchCats.Forbidden):
            return Response(status_code=403)
        raise TypeError("watchCats returned an unsupported response variant")

    async def __oapi_endpoint_export_cats(__oapi_http: Request) -> Response:
        __oapi_request = _contracts_ExportCats.Request()
        __oapi_result = await __oapi_handlers.cats.export_cats(__oapi_request)
        if isinstance(__oapi_result, _contracts_ExportCats.Ok):
            return _streams_StreamResponse(
                __oapi_result.body,
                encode=partial(
                    _streams_encode_json_item,
                    decoder=_export_cats_200_decoder,
                    media_type="application/jsonl",
                    checked=True,
                ),
                status_code=200,
                media_type="application/jsonl",
            )
        raise TypeError("exportCats returned an unsupported response variant")

    async def __oapi_endpoint_export_cats_ndjson(__oapi_http: Request) -> Response:
        __oapi_request = _contracts_ExportCatsNdjson.Request()
        __oapi_result = await __oapi_handlers.cats.export_cats_ndjson(__oapi_request)
        if isinstance(__oapi_result, _contracts_ExportCatsNdjson.Ok):
            return _streams_StreamResponse(
                __oapi_result.body,
                encode=partial(
                    _streams_encode_json_item,
                    decoder=_export_cats_ndjson_200_decoder,
                    media_type="application/x-ndjson",
                    checked=True,
                ),
                status_code=200,
                media_type="application/x-ndjson",
            )
        raise TypeError("exportCatsNdjson returned an unsupported response variant")

    async def __oapi_endpoint_export_cats_sequence(__oapi_http: Request) -> Response:
        __oapi_request = _contracts_ExportCatsSequence.Request()
        __oapi_result = await __oapi_handlers.cats.export_cats_sequence(__oapi_request)
        if isinstance(__oapi_result, _contracts_ExportCatsSequence.Ok):
            return _streams_StreamResponse(
                __oapi_result.body,
                encode=partial(
                    _streams_encode_json_item,
                    decoder=_export_cats_sequence_200_decoder,
                    media_type="application/json-seq",
                    checked=True,
                ),
                status_code=200,
                media_type="application/json-seq",
            )
        raise TypeError("exportCatsSequence returned an unsupported response variant")

    __oapi_routes = [
        Route(
            prefix + "/cats/events", __oapi_endpoint_watch_cats, methods=["GET"], name="watchCats"
        ),
        Route(
            prefix + "/cats/jsonl", __oapi_endpoint_export_cats, methods=["GET"], name="exportCats"
        ),
        Route(
            prefix + "/cats/ndjson",
            __oapi_endpoint_export_cats_ndjson,
            methods=["GET"],
            name="exportCatsNdjson",
        ),
        Route(
            prefix + "/cats/sequence",
            __oapi_endpoint_export_cats_sequence,
            methods=["GET"],
            name="exportCatsSequence",
        ),
    ]
    __oapi_routes[0].methods = {"GET"}
    __oapi_routes[1].methods = {"GET"}
    __oapi_routes[2].methods = {"GET"}
    __oapi_routes[3].methods = {"GET"}
    if include_schema:
        __oapi_schema = json.decode(Path(__file__).with_name("openapi.json").read_bytes())
        __oapi_schema["paths"] = {
            prefix + path: item for path, item in __oapi_schema["paths"].items()
        }
        __oapi_schema_bytes = _encoder.encode(__oapi_schema)

        async def __oapi_openapi(request: Request) -> Response:
            return Response(__oapi_schema_bytes, media_type="application/json")

        __oapi_routes.append(Route(prefix + "/openapi.json", __oapi_openapi))
    return Router(routes=__oapi_routes)
