# Copyright (c) 2021 CloudZero - ALL RIGHTS RESERVED - PROPRIETARY AND CONFIDENTIAL
# Unauthorized copying of this file and/or project, via any medium is strictly prohibited.
# Direct all questions to legal@cloudzero.com
# mypy: disable-error-code="empty-body"
from dataclasses import dataclass
from datetime import datetime
from typing import Dict, List, NamedTuple, Optional

from billing_iapi.types import CostType
from czc.type_util import deserializable
from data_access_controls_iapi.api.web.types import AuthorizationContext
from dimensions_iapi.models import Fqdid

from .common import invokes_billing_api
from .partition_type import PartitionType
from .types import GranularityType, PartitionSortDirection, PartitionSortType


class DateRange(NamedTuple):
    start: datetime
    end: datetime


@deserializable()
@dataclass(frozen=True)
class AvailableDimension:
    fqdid: Fqdid
    aliases: List[str]
    display_name: str
    legacy_partition_type: PartitionType
    hidden: bool


@deserializable()
@dataclass(frozen=True)
class AvailableDimensions:
    dimensions: List[AvailableDimension]


@invokes_billing_api(api='get-billing-data')
def get_billing_data(
    *,
    organization_id: str,
    date_range: DateRange,
    granularity: GranularityType = GranularityType.daily,
    partitions: Optional[List[PartitionType]] = None,
    filters: Optional[Dict[PartitionType, List[str]]] = None,
    cost_type: CostType = CostType.real_cost,
    authorization_context: Optional[AuthorizationContext] = None,
    align_to_granularity: bool = True,
):
    pass


@invokes_billing_api(api='get-data-projection:live')
def get_data_projection(
    *,
    organization_id: str,
    date_range: DateRange,
    dimensions: Dict[str, PartitionType],
    granularity: GranularityType = GranularityType.daily,
    filters: Optional[Dict[PartitionType, List[str]]] = None,
    authorization_context: Optional[AuthorizationContext] = None,
    data_access_column: Optional[str] = None,
    align_to_granularity: bool = True,
    include_projected_row_count: bool = False,
):
    pass


@invokes_billing_api(api='get-total-cost-per-hour')
def get_total_cost_per_hour(
    *, organization_id: str, date_range: DateRange, filters: Optional[Dict[PartitionType, List[str]]] = None
):
    pass


@invokes_billing_api(api='get-member-available-partitions-v2:live')
def get_member_available_partitions(*, organization_id: str, include_hidden: bool = False):
    pass


@invokes_billing_api(api='get-partition-values')
def get_partition_values(
    *,
    organization_id: str,
    partition: PartitionType,
    date_range: Optional[DateRange] = None,
    granularity: GranularityType = GranularityType.daily,
    match: Optional[str] = None,
    limit: Optional[int] = None,
):
    pass


@invokes_billing_api(api='get-active-telemetry-streams')
def get_active_telemetry_streams(*, organization_id: str):
    pass


@invokes_billing_api(api='get-available-dimensions')
def get_available_dimensions(*, organization_id: str, include_hidden: bool = False) -> AvailableDimensions:
    pass


@invokes_billing_api(api='get-resource-tags')
def get_resource_tags(*, organization_id: str, resource_id: str):
    pass


@invokes_billing_api(api='get-grouped-costs')
def get_grouped_costs(
    *,
    organization_id: str,
    partition_by: List[PartitionType],
    date_range: DateRange,
    granularity: GranularityType = GranularityType.daily,
    filters: Optional[Dict[PartitionType, List[str]]] = None,
    cost_type: Optional[List[CostType]] = None,
    partition_sort_by: Optional[str] = None,
    partition_sort_type: Optional[PartitionSortType] = None,
    partition_sort_direction: Optional[PartitionSortDirection] = None,
    max_partitions: Optional[int] = None,
    offset_partitions: Optional[int] = None,
    include_trends: bool = True,
    include_totals: bool = True,
):
    pass
