# This file was auto-generated by Fern from our API Definition.

import typing
from json.decoder import JSONDecodeError

from ...core.api_error import ApiError
from ...core.client_wrapper import AsyncClientWrapper, SyncClientWrapper
from ...core.jsonable_encoder import encode_path_param
from ...core.pagination import AsyncPager, SyncPager
from ...core.parse_error import ParsingError
from ...core.pydantic_utilities import parse_obj_as
from ...core.request_options import RequestOptions
from ...errors.bad_request_error import BadRequestError
from ...errors.forbidden_error import ForbiddenError
from ...errors.too_many_requests_error import TooManyRequestsError
from ...errors.unauthorized_error import UnauthorizedError
from ...types.log import Log
from ...types.user_list_log_offset_paginated_response_content import UserListLogOffsetPaginatedResponseContent
from pydantic import ValidationError


class RawLogsClient:
    def __init__(self, *, client_wrapper: SyncClientWrapper):
        self._client_wrapper = client_wrapper

    def list(
        self,
        id: str,
        *,
        page: typing.Optional[int] = 0,
        per_page: typing.Optional[int] = 50,
        sort: typing.Optional[str] = None,
        include_totals: typing.Optional[bool] = True,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> SyncPager[Log, UserListLogOffsetPaginatedResponseContent]:
        """
        Retrieve log events for a specific user.

        Note: For more information on all possible event types, their respective acronyms and descriptions, see <a href="https://auth0.com/docs/logs/log-event-type-codes">Log Event Type Codes</a>.

        For more information on the list of fields that can be used in `sort`, see <a href="https://auth0.com/docs/logs/log-search-query-syntax#searchable-fields">Searchable Fields</a>.

        Auth0 <a href="https://auth0.com/docs/logs/retrieve-log-events-using-mgmt-api#limitations">limits the number of logs</a> you can return by search criteria to 100 logs per request. Furthermore, you may only paginate through up to 1,000 search results. If you exceed this threshold, please redefine your search.

        Parameters
        ----------
        id : str
            ID of the user of the logs to retrieve

        page : typing.Optional[int]
            Page index of the results to return. First page is 0.

        per_page : typing.Optional[int]
            Number of results per page. Paging is disabled if parameter not sent.

        sort : typing.Optional[str]
            Field to sort by. Use `fieldname:1` for ascending order and `fieldname:-1` for descending.

        include_totals : typing.Optional[bool]
            Return results inside an object that contains the total result count (true) or as a direct array of results (false, default).

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        SyncPager[Log, UserListLogOffsetPaginatedResponseContent]
            Logs successfully retrieved.
        """
        page = page if page is not None else 0

        _response = self._client_wrapper.httpx_client.request(
            f"users/{encode_path_param(id)}/logs",
            method="GET",
            params={
                "page": page,
                "per_page": per_page,
                "sort": sort,
                "include_totals": include_totals,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    UserListLogOffsetPaginatedResponseContent,
                    parse_obj_as(
                        type_=UserListLogOffsetPaginatedResponseContent,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.logs
                _has_next = len(_items or []) > 0
                _get_next = lambda: self.list(
                    id,
                    page=page + 1,
                    per_page=per_page,
                    sort=sort,
                    include_totals=include_totals,
                    request_options=request_options,
                )
                return SyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        except ValidationError as e:
            raise ParsingError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
            )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)


class AsyncRawLogsClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def list(
        self,
        id: str,
        *,
        page: typing.Optional[int] = 0,
        per_page: typing.Optional[int] = 50,
        sort: typing.Optional[str] = None,
        include_totals: typing.Optional[bool] = True,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncPager[Log, UserListLogOffsetPaginatedResponseContent]:
        """
        Retrieve log events for a specific user.

        Note: For more information on all possible event types, their respective acronyms and descriptions, see <a href="https://auth0.com/docs/logs/log-event-type-codes">Log Event Type Codes</a>.

        For more information on the list of fields that can be used in `sort`, see <a href="https://auth0.com/docs/logs/log-search-query-syntax#searchable-fields">Searchable Fields</a>.

        Auth0 <a href="https://auth0.com/docs/logs/retrieve-log-events-using-mgmt-api#limitations">limits the number of logs</a> you can return by search criteria to 100 logs per request. Furthermore, you may only paginate through up to 1,000 search results. If you exceed this threshold, please redefine your search.

        Parameters
        ----------
        id : str
            ID of the user of the logs to retrieve

        page : typing.Optional[int]
            Page index of the results to return. First page is 0.

        per_page : typing.Optional[int]
            Number of results per page. Paging is disabled if parameter not sent.

        sort : typing.Optional[str]
            Field to sort by. Use `fieldname:1` for ascending order and `fieldname:-1` for descending.

        include_totals : typing.Optional[bool]
            Return results inside an object that contains the total result count (true) or as a direct array of results (false, default).

        request_options : typing.Optional[RequestOptions]
            Request-specific configuration.

        Returns
        -------
        AsyncPager[Log, UserListLogOffsetPaginatedResponseContent]
            Logs successfully retrieved.
        """
        page = page if page is not None else 0

        _response = await self._client_wrapper.httpx_client.request(
            f"users/{encode_path_param(id)}/logs",
            method="GET",
            params={
                "page": page,
                "per_page": per_page,
                "sort": sort,
                "include_totals": include_totals,
            },
            request_options=request_options,
        )
        try:
            if 200 <= _response.status_code < 300:
                _parsed_response = typing.cast(
                    UserListLogOffsetPaginatedResponseContent,
                    parse_obj_as(
                        type_=UserListLogOffsetPaginatedResponseContent,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                _items = _parsed_response.logs
                _has_next = len(_items or []) > 0

                async def _get_next():
                    return await self.list(
                        id,
                        page=page + 1,
                        per_page=per_page,
                        sort=sort,
                        include_totals=include_totals,
                        request_options=request_options,
                    )

                return AsyncPager(has_next=_has_next, items=_items, get_next=_get_next, response=_parsed_response)
            if _response.status_code == 400:
                raise BadRequestError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 401:
                raise UnauthorizedError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 403:
                raise ForbiddenError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            if _response.status_code == 429:
                raise TooManyRequestsError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        parse_obj_as(
                            type_=typing.Any,  # type: ignore
                            object_=_response.json(),
                        ),
                    ),
                )
            _response_json = _response.json()
        except JSONDecodeError:
            raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response.text)
        except ValidationError as e:
            raise ParsingError(
                status_code=_response.status_code, headers=dict(_response.headers), body=_response.json(), cause=e
            )
        raise ApiError(status_code=_response.status_code, headers=dict(_response.headers), body=_response_json)
