# -*- coding: utf-8 -*-
# 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

from datetime import datetime
from enum import Enum
from typing import Dict, List, NamedTuple, Optional, overload, Union

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

CostContextInstruction = dict


class CostContextDefinition(NamedTuple):
    name: str
    hidden: bool
    references: Dict[str, CostContextInstruction]
    value: CostContextInstruction
    id: Optional[str] = None
    aliases: Optional[List[str]] = []


GroupContextDefinition = CostContextDefinition


class TelemetryCostContextDefinition(NamedTuple):
    name: str
    hidden: bool
    telemetry_streams: List[str]
    id: Optional[str] = None
    aliases: Optional[List[str]] = []


class AllocationMethod(Enum):
    proportional = 'proportional'
    even = 'even'


class AllocationRulesCostContextDefinition(NamedTuple):
    name: str
    hidden: bool
    across_elements: Dict[str, Union[Dict[str, CostContextInstruction], CostContextInstruction]]
    spend_to_allocate: Dict[str, Union[Dict[str, CostContextInstruction], CostContextInstruction]]
    for_each_element_of: Optional[Dict[str, Union[Dict[str, CostContextInstruction], CostContextInstruction]]] = None
    allocation_method: Optional[AllocationMethod] = None
    id: Optional[str] = None
    aliases: Optional[List[str]] = []


class Instructions(NamedTuple):
    group: Optional[List[GroupContextDefinition]] = None
    telemetry: Optional[List[TelemetryCostContextDefinition]] = None
    allocation_rules: Optional[List[AllocationRulesCostContextDefinition]] = None


@invokes_billing_api(api='get-used-partition-types')
def get_used_partition_types(*, organization_id: str) -> List[PartitionType]:
    pass


@overload
def update_cost_context_definitions(*, organization_id: str,
                                    instructions: List[GroupContextDefinition]):
    pass


@overload
def update_cost_context_definitions(*, organization_id: str,
                                    instructions: Instructions):
    pass


@invokes_billing_api(api='update-cost-context-definitions')
def update_cost_context_definitions(*, organization_id: str, instructions):
    pass


@invokes_billing_api(api='get-mcv-for-instructions')
def get_member_cost_view_for_instructions(
        *,
        organization_id: str,
        instructions: List[dict],
        partition_by: PartitionType,
        granularity: GranularityType,
        start_date: datetime,
        end_date: datetime,
        filters: Dict[PartitionType, List[str]] = None,
        cost_type: CostType = None,
        max_partitions: int = None,
        partition_sort_type: PartitionSortType = None,
        partition_sort_direction: PartitionSortDirection = None,
        allow_allocation_dimensions: bool = False):
    pass
