# coding: utf-8
"""Waylay Broker api.

This code was generated from the OpenAPI documentation of 'Waylay Broker'

Generated by OpenAPI Generator (https://openapi-generator.tech)

Do not edit the class manually.
"""

from __future__ import annotations  # for Python 3.7–3.9

from typing import (
    TYPE_CHECKING,
    Any,
    Dict,
    Literal,
    Optional,
    TypeVar,
    overload,
)

from pydantic import (
    Field,
    StrictBool,
    StrictStr,
    TypeAdapter,
)
from typing_extensions import (
    Annotated,  # >=3.9,
)
from waylay.sdk.api import (
    HeaderTypes,
    QueryParamTypes,
    Response,
)
from waylay.sdk.api._models import Model
from waylay.sdk.plugin import WithApiClient

if TYPE_CHECKING:
    from waylay.services.data.models import (
        DeleteMessages200Response,
        ErrorResponse,
        PostSeriesForResourceRequest,
        PostSeriesRequest,
        PublishEventResponse,
        PublishResourceEventResponse,
        TimestampedResourceEvent,
    )
    from waylay.services.data.queries.events_api import (
        PostSeriesForResourceQuery,
        PostSeriesQuery,
        RemoveQuery,
        StreamEventsQuery,
    )


try:
    from waylay.services.data.models import (
        DeleteMessages200Response,
        ErrorResponse,
        PostSeriesForResourceRequest,
        PostSeriesRequest,
        PublishEventResponse,
        PublishResourceEventResponse,
        TimestampedResourceEvent,
    )
    from waylay.services.data.queries.events_api import (
        PostSeriesForResourceQuery,
        PostSeriesQuery,
        RemoveQuery,
        StreamEventsQuery,
    )

    MODELS_AVAILABLE = True
except ImportError:
    MODELS_AVAILABLE = False

    if not TYPE_CHECKING:
        PostSeriesRequest = Model

        PostSeriesQuery = dict
        PublishEventResponse = Model

        ErrorResponse = Model

        PostSeriesForResourceRequest = Model

        PostSeriesForResourceQuery = dict
        PublishResourceEventResponse = Model

        ErrorResponse = Model

        RemoveQuery = dict
        DeleteMessages200Response = Model

        ErrorResponse = Model

        StreamEventsQuery = dict
        TimestampedResourceEvent = Model

        ErrorResponse = Model


T = TypeVar("T")


class EventsApi(WithApiClient):
    """EventsApi service methods.

    NOTE: This class is auto generated by OpenAPI Generator
    Ref: https://openapi-generator.tech

    Do not edit the class manually.
    """

    @overload
    async def post_series(
        self,
        *,
        json: PostSeriesRequest | None = None,
        query: PostSeriesQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: Literal[""] = "",
        response_type: Literal[None] = None,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> PublishEventResponse: ...

    @overload
    async def post_series(
        self,
        *,
        json: PostSeriesRequest | None = None,
        query: PostSeriesQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: Literal[""] = "",
        response_type: T,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> T: ...

    @overload
    async def post_series(
        self,
        *,
        json: PostSeriesRequest | None = None,
        query: PostSeriesQuery | QueryParamTypes | None = None,
        raw_response: Literal[True],
        select_path: Literal["_not_used_"] = "_not_used_",
        response_type: Literal[None] = None,  # not used
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> Response: ...

    @overload
    async def post_series(
        self,
        *,
        json: PostSeriesRequest | None = None,
        query: PostSeriesQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: str,
        response_type: Literal[None] = None,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> Model: ...

    @overload
    async def post_series(
        self,
        *,
        json: PostSeriesRequest | None = None,
        query: PostSeriesQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: str,
        response_type: T,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> T: ...

    async def post_series(
        self,
        *,
        json: PostSeriesRequest | None = None,
        query: PostSeriesQuery | QueryParamTypes | None = None,
        raw_response: StrictBool = False,
        select_path: str = "",
        response_type: T | None = None,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> PublishEventResponse | T | Response | Model:
        """Post Events.

        Pushes events to broker.
        :param json: The json request body.
        :type json: PostSeriesRequest, optional
        :param query: URL Query parameters.
        :type query: PostSeriesQuery | QueryParamTypes, optional
        :param query['forward'] (dict) <br> query.forward (Query) : If payload is a single event, _Events_ are forwarded to the [Rule Engine](/#/api/rules/) unless `forward` is explicitly set to `false`. If payload has multiple events and each event is for a distinct resource, all _Events_ are forwarded to the [Rule Engine](/#/api/rules/) unless `forward` is explicitly set to `false` If payload has multiple events and there are multiple events for the same resource, an error will be returned if `forward` is explicitly set to `true`.
        :type query['forward']: bool
        :param query['store'] (dict) <br> query.store (Query) : Unless explicitly set to `false`, _Events_ are stored  into message cache, and their scalar attributes stored in the time series database.
        :type query['store']: bool
        :param query['ttl'] (dict) <br> query.ttl (Query) : Specifies how long data persists in both the message cache and time series database.
        :type query['ttl']: TTLDuration
        :param raw_response: If true, return the http Response object instead of returning an api model object, or throwing an ApiError.
        :param select_path: Denotes the json path applied to the response object before returning it.
                Set it to the empty string `""` to receive the full response object.
        :param response_type: If specified, the response is parsed into an instance of the specified type.
        :param headers: Header parameters for this request
        :type headers: dict, optional
        :param `**kwargs`: Additional parameters passed on to the http client.
            See below.
        :Keyword Arguments:
            * timeout: a single numeric timeout in seconds,
                or a tuple of _connect_, _read_, _write_ and _pool_ timeouts.
            * stream: if true, the response will be in streaming mode
            * cookies
            * extensions
            * auth
            * follow_redirects: bool

        :return: Returns the result object if the http request succeeded with status code '2XX'.
        :raises APIError: If the http request has a status code different from `2XX`. This
            object wraps both the http Response and any parsed data.
        """

        should_validate = (
            MODELS_AVAILABLE and self.api_client.config.client_side_validation
        )

        # path parameters
        path_params: Dict[str, str] = {}

        ## named body parameters
        body_args: Dict[str, Any] = {}
        if json is not None and should_validate:
            body_adapter = TypeAdapter(Optional[PostSeriesRequest])
            json = body_adapter.validate_python(json)  # type: ignore # https://github.com/pydantic/pydantic/discussions/7094
        body_args["json"] = json

        # query parameters
        if query is not None and should_validate:
            query = TypeAdapter(PostSeriesQuery).validate_python(query)

        response_types_map: Dict[str, Any] = (
            {"2XX": response_type}
            if response_type is not None
            else {
                "200": PublishEventResponse if not select_path else Model,
            }
        )
        non_200_response_types_map: Dict[str, Any] = {
            "400": ErrorResponse,
        }
        response_types_map.update(non_200_response_types_map)

        ## peform request
        return await self.api_client.request(
            method="POST",
            resource_path="/data/v1/events",
            path_params=path_params,
            params=query,
            **body_args,
            headers=headers,
            **kwargs,
            response_types_map=response_types_map,
            select_path=select_path,
            raw_response=raw_response,
        )

    @overload
    async def post_series_for_resource(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        json: PostSeriesForResourceRequest | None = None,
        query: PostSeriesForResourceQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: Literal[""] = "",
        response_type: Literal[None] = None,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> PublishResourceEventResponse: ...

    @overload
    async def post_series_for_resource(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        json: PostSeriesForResourceRequest | None = None,
        query: PostSeriesForResourceQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: Literal[""] = "",
        response_type: T,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> T: ...

    @overload
    async def post_series_for_resource(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        json: PostSeriesForResourceRequest | None = None,
        query: PostSeriesForResourceQuery | QueryParamTypes | None = None,
        raw_response: Literal[True],
        select_path: Literal["_not_used_"] = "_not_used_",
        response_type: Literal[None] = None,  # not used
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> Response: ...

    @overload
    async def post_series_for_resource(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        json: PostSeriesForResourceRequest | None = None,
        query: PostSeriesForResourceQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: str,
        response_type: Literal[None] = None,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> Model: ...

    @overload
    async def post_series_for_resource(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        json: PostSeriesForResourceRequest | None = None,
        query: PostSeriesForResourceQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: str,
        response_type: T,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> T: ...

    async def post_series_for_resource(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        json: PostSeriesForResourceRequest | None = None,
        query: PostSeriesForResourceQuery | QueryParamTypes | None = None,
        raw_response: StrictBool = False,
        select_path: str = "",
        response_type: T | None = None,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> PublishResourceEventResponse | T | Response | Model:
        """Post Events For Resource.

        Pushes events for a given resource to broker.
        :param resource_id: Uniquely identifies a resource. (required)
        :type resource_id: str
        :param json: The json request body.
        :type json: PostSeriesForResourceRequest, optional
        :param query: URL Query parameters.
        :type query: PostSeriesForResourceQuery | QueryParamTypes, optional
        :param query['forward'] (dict) <br> query.forward (Query) : If payload is a single event, _Events_ are forwarded to the [Rule Engine](/#/api/rules/) unless `forward` is explicitly set to `false`. If payload has multiple events, this parameter is ignored and _Events_ will only be stored into message cache and their scalar attributes in the timeseries database.
        :type query['forward']: bool
        :param query['store'] (dict) <br> query.store (Query) : Unless explicitly set to `false`, _Events_ are stored  into message cache, and their scalar attributes stored in the time series database.
        :type query['store']: bool
        :param query['ttl'] (dict) <br> query.ttl (Query) : Specifies how long data persists in both the message cache and time series database.
        :type query['ttl']: TTLDuration
        :param raw_response: If true, return the http Response object instead of returning an api model object, or throwing an ApiError.
        :param select_path: Denotes the json path applied to the response object before returning it.
                Set it to the empty string `""` to receive the full response object.
        :param response_type: If specified, the response is parsed into an instance of the specified type.
        :param headers: Header parameters for this request
        :type headers: dict, optional
        :param `**kwargs`: Additional parameters passed on to the http client.
            See below.
        :Keyword Arguments:
            * timeout: a single numeric timeout in seconds,
                or a tuple of _connect_, _read_, _write_ and _pool_ timeouts.
            * stream: if true, the response will be in streaming mode
            * cookies
            * extensions
            * auth
            * follow_redirects: bool

        :return: Returns the result object if the http request succeeded with status code '2XX'.
        :raises APIError: If the http request has a status code different from `2XX`. This
            object wraps both the http Response and any parsed data.
        """

        should_validate = (
            MODELS_AVAILABLE and self.api_client.config.client_side_validation
        )

        # path parameters
        path_params: Dict[str, str] = {
            "resourceId": str(resource_id),
        }

        ## named body parameters
        body_args: Dict[str, Any] = {}
        if json is not None and should_validate:
            body_adapter = TypeAdapter(Optional[PostSeriesForResourceRequest])
            json = body_adapter.validate_python(json)  # type: ignore # https://github.com/pydantic/pydantic/discussions/7094
        body_args["json"] = json

        # query parameters
        if query is not None and should_validate:
            query = TypeAdapter(PostSeriesForResourceQuery).validate_python(query)

        response_types_map: Dict[str, Any] = (
            {"2XX": response_type}
            if response_type is not None
            else {
                "200": PublishResourceEventResponse if not select_path else Model,
            }
        )
        non_200_response_types_map: Dict[str, Any] = {
            "400": ErrorResponse,
        }
        response_types_map.update(non_200_response_types_map)

        ## peform request
        return await self.api_client.request(
            method="POST",
            resource_path="/data/v1/events/{resourceId}",
            path_params=path_params,
            params=query,
            **body_args,
            headers=headers,
            **kwargs,
            response_types_map=response_types_map,
            select_path=select_path,
            raw_response=raw_response,
        )

    @overload
    async def remove(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        query: RemoveQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: Literal[""] = "",
        response_type: Literal[None] = None,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> DeleteMessages200Response: ...

    @overload
    async def remove(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        query: RemoveQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: Literal[""] = "",
        response_type: T,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> T: ...

    @overload
    async def remove(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        query: RemoveQuery | QueryParamTypes | None = None,
        raw_response: Literal[True],
        select_path: Literal["_not_used_"] = "_not_used_",
        response_type: Literal[None] = None,  # not used
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> Response: ...

    @overload
    async def remove(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        query: RemoveQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: str,
        response_type: Literal[None] = None,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> Model: ...

    @overload
    async def remove(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        query: RemoveQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: str,
        response_type: T,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> T: ...

    async def remove(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        query: RemoveQuery | QueryParamTypes | None = None,
        raw_response: StrictBool = False,
        select_path: str = "",
        response_type: T | None = None,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> DeleteMessages200Response | T | Response | Model:
        """Remove Data.

        Removes all data for a resource.
        :param resource_id: Uniquely identifies a resource. (required)
        :type resource_id: str
        :param query: URL Query parameters.
        :type query: RemoveQuery | QueryParamTypes, optional
        :param query['from'] (dict) <br> query.var_from (Query) : Specifies the lower bound of the time period
        :type query['from']: DeleteSeriesFromParameter
        :param query['until'] (dict) <br> query.until (Query) : Specifies the upper bound of the time period
        :type query['until']: DeleteSeriesFromParameter
        :param query['onlytimeseries'] (dict) <br> query.onlytimeseries (Query) : if set to `true` will only delete timeseries data
        :type query['onlytimeseries']: bool
        :param raw_response: If true, return the http Response object instead of returning an api model object, or throwing an ApiError.
        :param select_path: Denotes the json path applied to the response object before returning it.
                Set it to the empty string `""` to receive the full response object.
        :param response_type: If specified, the response is parsed into an instance of the specified type.
        :param headers: Header parameters for this request
        :type headers: dict, optional
        :param `**kwargs`: Additional parameters passed on to the http client.
            See below.
        :Keyword Arguments:
            * timeout: a single numeric timeout in seconds,
                or a tuple of _connect_, _read_, _write_ and _pool_ timeouts.
            * stream: if true, the response will be in streaming mode
            * cookies
            * extensions
            * auth
            * follow_redirects: bool

        :return: Returns the result object if the http request succeeded with status code '2XX'.
        :raises APIError: If the http request has a status code different from `2XX`. This
            object wraps both the http Response and any parsed data.
        """

        should_validate = (
            MODELS_AVAILABLE and self.api_client.config.client_side_validation
        )

        # path parameters
        path_params: Dict[str, str] = {
            "resourceId": str(resource_id),
        }

        ## named body parameters
        body_args: Dict[str, Any] = {}

        # query parameters
        if query is not None and should_validate:
            query = TypeAdapter(RemoveQuery).validate_python(query)

        response_types_map: Dict[str, Any] = (
            {"2XX": response_type}
            if response_type is not None
            else {
                "200": DeleteMessages200Response if not select_path else Model,
            }
        )
        non_200_response_types_map: Dict[str, Any] = {
            "400": ErrorResponse,
        }
        response_types_map.update(non_200_response_types_map)

        ## peform request
        return await self.api_client.request(
            method="DELETE",
            resource_path="/data/v1/{resourceId}",
            path_params=path_params,
            params=query,
            **body_args,
            headers=headers,
            **kwargs,
            response_types_map=response_types_map,
            select_path=select_path,
            raw_response=raw_response,
        )

    @overload
    async def stream_events(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        query: StreamEventsQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: Literal[""] = "",
        response_type: Literal[None] = None,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> TimestampedResourceEvent: ...

    @overload
    async def stream_events(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        query: StreamEventsQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: Literal[""] = "",
        response_type: T,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> T: ...

    @overload
    async def stream_events(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        query: StreamEventsQuery | QueryParamTypes | None = None,
        raw_response: Literal[True],
        select_path: Literal["_not_used_"] = "_not_used_",
        response_type: Literal[None] = None,  # not used
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> Response: ...

    @overload
    async def stream_events(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        query: StreamEventsQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: str,
        response_type: Literal[None] = None,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> Model: ...

    @overload
    async def stream_events(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        query: StreamEventsQuery | QueryParamTypes | None = None,
        raw_response: Literal[False] = False,
        select_path: str,
        response_type: T,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> T: ...

    async def stream_events(
        self,
        resource_id: Annotated[
            StrictStr, Field(description="Uniquely identifies a resource.")
        ],
        *,
        query: StreamEventsQuery | QueryParamTypes | None = None,
        raw_response: StrictBool = False,
        select_path: str = "",
        response_type: T | None = None,
        headers: HeaderTypes | None = None,
        **kwargs,
    ) -> TimestampedResourceEvent | T | Response | Model:
        """Stream Events For Resource.

        Opens a data stream for the _Events_ of the given _Resource_.
        :param resource_id: Uniquely identifies a resource. (required)
        :type resource_id: str
        :param query: URL Query parameters.
        :type query: StreamEventsQuery | QueryParamTypes, optional
        :param raw_response: If true, return the http Response object instead of returning an api model object, or throwing an ApiError.
        :param select_path: Denotes the json path applied to the response object before returning it.
                Set it to the empty string `""` to receive the full response object.
        :param response_type: If specified, the response is parsed into an instance of the specified type.
        :param headers: Header parameters for this request
        :type headers: dict, optional
        :param `**kwargs`: Additional parameters passed on to the http client.
            See below.
        :Keyword Arguments:
            * timeout: a single numeric timeout in seconds,
                or a tuple of _connect_, _read_, _write_ and _pool_ timeouts.
            * stream: if true, the response will be in streaming mode
            * cookies
            * extensions
            * auth
            * follow_redirects: bool

        :return: Returns the result object if the http request succeeded with status code '2XX'.
        :raises APIError: If the http request has a status code different from `2XX`. This
            object wraps both the http Response and any parsed data.
        """

        should_validate = (
            MODELS_AVAILABLE and self.api_client.config.client_side_validation
        )

        # path parameters
        path_params: Dict[str, str] = {
            "resourceId": str(resource_id),
        }

        ## named body parameters
        body_args: Dict[str, Any] = {}

        # query parameters
        if query is not None and should_validate:
            query = TypeAdapter(StreamEventsQuery).validate_python(query)

        response_types_map: Dict[str, Any] = (
            {"2XX": response_type}
            if response_type is not None
            else {
                "200": TimestampedResourceEvent if not select_path else Model,
            }
        )
        non_200_response_types_map: Dict[str, Any] = {
            "406": ErrorResponse,
        }
        response_types_map.update(non_200_response_types_map)

        ## peform request
        return await self.api_client.request(
            method="GET",
            resource_path="/data/v1/events/{resourceId}",
            path_params=path_params,
            params=query,
            **body_args,
            headers=headers,
            **kwargs,
            response_types_map=response_types_map,
            select_path=select_path,
            raw_response=raw_response,
        )
