# 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.http_response import AsyncHttpResponse, HttpResponse
from ...core.parse_error import ParsingError
from ...core.request_options import RequestOptions
from ...core.serialization import convert_and_respect_annotation_metadata
from ...core.unchecked_base_model import construct_type
from ...errors.unprocessable_entity_error import UnprocessableEntityError
from ...types.column_filter import ColumnFilter
from ...types.workspace_analytics_query_response_model import WorkspaceAnalyticsQueryResponseModel
from .types.body_get_workspace_usage_v_1_workspace_analytics_query_usage_by_product_over_time_post_group_by_item import (
    BodyGetWorkspaceUsageV1WorkspaceAnalyticsQueryUsageByProductOverTimePostGroupByItem,
)
from pydantic import ValidationError

# this is used as the default value for optional parameters
OMIT = typing.cast(typing.Any, ...)


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

    def get_usage_by_product_over_time(
        self,
        *,
        start_time: int,
        end_time: int,
        interval_seconds: typing.Optional[int] = OMIT,
        group_by: typing.Optional[
            typing.Sequence[BodyGetWorkspaceUsageV1WorkspaceAnalyticsQueryUsageByProductOverTimePostGroupByItem]
        ] = OMIT,
        filters: typing.Optional[typing.Sequence[ColumnFilter]] = OMIT,
        time_zone: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> HttpResponse[WorkspaceAnalyticsQueryResponseModel]:
        """
        Returns credit usage broken down by product type over time. The response is a tabular structure with columns, column_types, column_units, and rows.

        Parameters
        ----------
        start_time : int
            Start of the time range as a Unix timestamp in milliseconds. Must be at least 2020-01-01.

        end_time : int
            End of the time range as a Unix timestamp in milliseconds. Must be at least 2020-01-01.

        interval_seconds : typing.Optional[int]
            Bucket size in seconds. Each row in the response covers this many seconds of the selected time range. For example, pass 3600 for hourly buckets or 86400 for daily buckets. Whether `time_zone` shifts bucket boundaries depends on this value: whole-day multiples (e.g. 86400) align to local midnight; whole-hour multiples up to 24 hours (e.g. 3600, 14400) align to local hour boundaries from midnight; sub-hour values and other sizes remain UTC-anchored regardless of `time_zone`.

        group_by : typing.Optional[typing.Sequence[BodyGetWorkspaceUsageV1WorkspaceAnalyticsQueryUsageByProductOverTimePostGroupByItem]]

        filters : typing.Optional[typing.Sequence[ColumnFilter]]

        time_zone : typing.Optional[str]
            IANA time zone identifier (e.g. 'America/New_York', 'Europe/London', 'UTC') used to align bucket boundaries for eligible `interval_seconds` values. Whole-day multiples start at local midnight; whole-hour multiples up to 24 hours align to local hour boundaries from midnight. Sub-hour intervals and other bucket sizes remain UTC-anchored regardless of this setting. Defaults to UTC.

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

        Returns
        -------
        HttpResponse[WorkspaceAnalyticsQueryResponseModel]
            Successful Response
        """
        _response = self._client_wrapper.httpx_client.request(
            "v1/workspace/analytics/query/usage-by-product-over-time",
            method="POST",
            json={
                "start_time": start_time,
                "end_time": end_time,
                "interval_seconds": interval_seconds,
                "group_by": group_by,
                "filters": convert_and_respect_annotation_metadata(
                    object_=filters, annotation=typing.Sequence[ColumnFilter], direction="write"
                ),
                "time_zone": time_zone,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    WorkspaceAnalyticsQueryResponseModel,
                    construct_type(
                        type_=WorkspaceAnalyticsQueryResponseModel,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return HttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        construct_type(
                            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 AsyncRawUsageClient:
    def __init__(self, *, client_wrapper: AsyncClientWrapper):
        self._client_wrapper = client_wrapper

    async def get_usage_by_product_over_time(
        self,
        *,
        start_time: int,
        end_time: int,
        interval_seconds: typing.Optional[int] = OMIT,
        group_by: typing.Optional[
            typing.Sequence[BodyGetWorkspaceUsageV1WorkspaceAnalyticsQueryUsageByProductOverTimePostGroupByItem]
        ] = OMIT,
        filters: typing.Optional[typing.Sequence[ColumnFilter]] = OMIT,
        time_zone: typing.Optional[str] = OMIT,
        request_options: typing.Optional[RequestOptions] = None,
    ) -> AsyncHttpResponse[WorkspaceAnalyticsQueryResponseModel]:
        """
        Returns credit usage broken down by product type over time. The response is a tabular structure with columns, column_types, column_units, and rows.

        Parameters
        ----------
        start_time : int
            Start of the time range as a Unix timestamp in milliseconds. Must be at least 2020-01-01.

        end_time : int
            End of the time range as a Unix timestamp in milliseconds. Must be at least 2020-01-01.

        interval_seconds : typing.Optional[int]
            Bucket size in seconds. Each row in the response covers this many seconds of the selected time range. For example, pass 3600 for hourly buckets or 86400 for daily buckets. Whether `time_zone` shifts bucket boundaries depends on this value: whole-day multiples (e.g. 86400) align to local midnight; whole-hour multiples up to 24 hours (e.g. 3600, 14400) align to local hour boundaries from midnight; sub-hour values and other sizes remain UTC-anchored regardless of `time_zone`.

        group_by : typing.Optional[typing.Sequence[BodyGetWorkspaceUsageV1WorkspaceAnalyticsQueryUsageByProductOverTimePostGroupByItem]]

        filters : typing.Optional[typing.Sequence[ColumnFilter]]

        time_zone : typing.Optional[str]
            IANA time zone identifier (e.g. 'America/New_York', 'Europe/London', 'UTC') used to align bucket boundaries for eligible `interval_seconds` values. Whole-day multiples start at local midnight; whole-hour multiples up to 24 hours align to local hour boundaries from midnight. Sub-hour intervals and other bucket sizes remain UTC-anchored regardless of this setting. Defaults to UTC.

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

        Returns
        -------
        AsyncHttpResponse[WorkspaceAnalyticsQueryResponseModel]
            Successful Response
        """
        _response = await self._client_wrapper.httpx_client.request(
            "v1/workspace/analytics/query/usage-by-product-over-time",
            method="POST",
            json={
                "start_time": start_time,
                "end_time": end_time,
                "interval_seconds": interval_seconds,
                "group_by": group_by,
                "filters": convert_and_respect_annotation_metadata(
                    object_=filters, annotation=typing.Sequence[ColumnFilter], direction="write"
                ),
                "time_zone": time_zone,
            },
            headers={
                "content-type": "application/json",
            },
            request_options=request_options,
            omit=OMIT,
        )
        try:
            if 200 <= _response.status_code < 300:
                _data = typing.cast(
                    WorkspaceAnalyticsQueryResponseModel,
                    construct_type(
                        type_=WorkspaceAnalyticsQueryResponseModel,  # type: ignore
                        object_=_response.json(),
                    ),
                )
                return AsyncHttpResponse(response=_response, data=_data)
            if _response.status_code == 422:
                raise UnprocessableEntityError(
                    headers=dict(_response.headers),
                    body=typing.cast(
                        typing.Any,
                        construct_type(
                            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)
