# SPDX-FileCopyrightText: Contributors to the Power Grid Model project <powergridmodel@lfenergy.org>
#
# SPDX-License-Identifier: MPL-2.0

"""Data types for power grid model dataset and component types."""

# This file is automatically generated. DO NOT modify it manually!

from collections.abc import Mapping
from enum import EnumMeta, StrEnum
from typing import TypeVar

# fmt: off

class _MetaEnum(EnumMeta):
    def __contains__(cls, member):
        """
        Check if member is part of the Enum.

        Args:
            member: Member to check.

        Returns:
            bool: True if the member is part of the Enum, False otherwise.
        """
        return member in cls.__members__


class DatasetType(StrEnum, metaclass=_MetaEnum):
    """
    A DatasetType is the type of a :class:`Dataset` in power grid model.

    - Examples:

        - DatasetType.input = "input"
        - DatasetType.update = "update"
    """

    input = "input"
    sym_output = "sym_output"
    asym_output = "asym_output"
    update = "update"
    sc_output = "sc_output"

    def __repr__(self):
        return self.value


class ComponentType(StrEnum, metaclass=_MetaEnum):
    """
    A ComponentType is the type of a grid component.

    - Examples:

        - ComponentType.node = "node"
        - ComponentType.line = "line"
    """

    node = "node"
    line = "line"
    asym_line = "asym_line"
    link = "link"
    generic_branch = "generic_branch"
    transformer = "transformer"
    transformer_tap_regulator = "transformer_tap_regulator"
    three_winding_transformer = "three_winding_transformer"
    sym_load = "sym_load"
    sym_gen = "sym_gen"
    asym_load = "asym_load"
    asym_gen = "asym_gen"
    voltage_regulator = "voltage_regulator"
    shunt = "shunt"
    source = "source"
    sym_voltage_sensor = "sym_voltage_sensor"
    asym_voltage_sensor = "asym_voltage_sensor"
    sym_power_sensor = "sym_power_sensor"
    asym_power_sensor = "asym_power_sensor"
    sym_current_sensor = "sym_current_sensor"
    asym_current_sensor = "asym_current_sensor"
    fault = "fault"

    def __repr__(self):
        return self.value

class AttributeType(StrEnum, metaclass=_MetaEnum):
    """
    An AttributeType is the attribute of a grid component.

    - Examples:

        - AttributeType.p_from = "p_from"
        - AttributeType.u_pu = "u_pu"
    """

    angle_measurement_type = "angle_measurement_type"
    b0 = "b0"
    b1 = "b1"
    c0 = "c0"
    c1 = "c1"
    c_aa = "c_aa"
    c_ba = "c_ba"
    c_bb = "c_bb"
    c_ca = "c_ca"
    c_cb = "c_cb"
    c_cc = "c_cc"
    clock = "clock"
    clock_12 = "clock_12"
    clock_13 = "clock_13"
    control_side = "control_side"
    energized = "energized"
    fault_object = "fault_object"
    fault_phase = "fault_phase"
    fault_type = "fault_type"
    from_node = "from_node"
    from_status = "from_status"
    g0 = "g0"
    g1 = "g1"
    i = "i"
    i0 = "i0"
    i0_zero_sequence = "i0_zero_sequence"
    i_1 = "i_1"
    i_1_angle = "i_1_angle"
    i_2 = "i_2"
    i_2_angle = "i_2_angle"
    i_3 = "i_3"
    i_3_angle = "i_3_angle"
    i_angle = "i_angle"
    i_angle_measured = "i_angle_measured"
    i_angle_residual = "i_angle_residual"
    i_angle_sigma = "i_angle_sigma"
    i_f = "i_f"
    i_f_angle = "i_f_angle"
    i_from = "i_from"
    i_from_angle = "i_from_angle"
    i_measured = "i_measured"
    i_n = "i_n"
    i_residual = "i_residual"
    i_sigma = "i_sigma"
    i_to = "i_to"
    i_to_angle = "i_to_angle"
    id = "id"
    k = "k"
    limit_violated = "limit_violated"
    line_drop_compensation_r = "line_drop_compensation_r"
    line_drop_compensation_x = "line_drop_compensation_x"
    loading = "loading"
    loading_1 = "loading_1"
    loading_2 = "loading_2"
    loading_3 = "loading_3"
    measured_object = "measured_object"
    measured_terminal_type = "measured_terminal_type"
    node = "node"
    node_1 = "node_1"
    node_2 = "node_2"
    node_3 = "node_3"
    p = "p"
    p0 = "p0"
    p0_zero_sequence = "p0_zero_sequence"
    p_1 = "p_1"
    p_2 = "p_2"
    p_3 = "p_3"
    p_from = "p_from"
    p_measured = "p_measured"
    p_residual = "p_residual"
    p_sigma = "p_sigma"
    p_specified = "p_specified"
    p_to = "p_to"
    pf = "pf"
    pk = "pk"
    pk_12 = "pk_12"
    pk_12_max = "pk_12_max"
    pk_12_min = "pk_12_min"
    pk_13 = "pk_13"
    pk_13_max = "pk_13_max"
    pk_13_min = "pk_13_min"
    pk_23 = "pk_23"
    pk_23_max = "pk_23_max"
    pk_23_min = "pk_23_min"
    pk_max = "pk_max"
    pk_min = "pk_min"
    power_sigma = "power_sigma"
    q = "q"
    q_1 = "q_1"
    q_2 = "q_2"
    q_3 = "q_3"
    q_from = "q_from"
    q_max = "q_max"
    q_measured = "q_measured"
    q_min = "q_min"
    q_residual = "q_residual"
    q_sigma = "q_sigma"
    q_specified = "q_specified"
    q_to = "q_to"
    r0 = "r0"
    r1 = "r1"
    r_aa = "r_aa"
    r_ba = "r_ba"
    r_bb = "r_bb"
    r_ca = "r_ca"
    r_cb = "r_cb"
    r_cc = "r_cc"
    r_f = "r_f"
    r_grounding_1 = "r_grounding_1"
    r_grounding_2 = "r_grounding_2"
    r_grounding_3 = "r_grounding_3"
    r_grounding_from = "r_grounding_from"
    r_grounding_to = "r_grounding_to"
    r_na = "r_na"
    r_nb = "r_nb"
    r_nc = "r_nc"
    r_nn = "r_nn"
    regulated_object = "regulated_object"
    rx_ratio = "rx_ratio"
    s = "s"
    s_1 = "s_1"
    s_2 = "s_2"
    s_3 = "s_3"
    s_from = "s_from"
    s_to = "s_to"
    sk = "sk"
    sn = "sn"
    sn_1 = "sn_1"
    sn_2 = "sn_2"
    sn_3 = "sn_3"
    status = "status"
    status_1 = "status_1"
    status_2 = "status_2"
    status_3 = "status_3"
    tan0 = "tan0"
    tan1 = "tan1"
    tap_max = "tap_max"
    tap_min = "tap_min"
    tap_nom = "tap_nom"
    tap_pos = "tap_pos"
    tap_side = "tap_side"
    tap_size = "tap_size"
    theta = "theta"
    to_node = "to_node"
    to_status = "to_status"
    type = "type"
    u = "u"
    u1 = "u1"
    u2 = "u2"
    u3 = "u3"
    u_angle = "u_angle"
    u_angle_measured = "u_angle_measured"
    u_angle_residual = "u_angle_residual"
    u_band = "u_band"
    u_measured = "u_measured"
    u_pu = "u_pu"
    u_rated = "u_rated"
    u_ref = "u_ref"
    u_ref_angle = "u_ref_angle"
    u_residual = "u_residual"
    u_set = "u_set"
    u_sigma = "u_sigma"
    uk = "uk"
    uk_12 = "uk_12"
    uk_12_max = "uk_12_max"
    uk_12_min = "uk_12_min"
    uk_13 = "uk_13"
    uk_13_max = "uk_13_max"
    uk_13_min = "uk_13_min"
    uk_23 = "uk_23"
    uk_23_max = "uk_23_max"
    uk_23_min = "uk_23_min"
    uk_max = "uk_max"
    uk_min = "uk_min"
    winding_1 = "winding_1"
    winding_2 = "winding_2"
    winding_3 = "winding_3"
    winding_from = "winding_from"
    winding_to = "winding_to"
    x0 = "x0"
    x1 = "x1"
    x_aa = "x_aa"
    x_ba = "x_ba"
    x_bb = "x_bb"
    x_ca = "x_ca"
    x_cb = "x_cb"
    x_cc = "x_cc"
    x_f = "x_f"
    x_grounding_1 = "x_grounding_1"
    x_grounding_2 = "x_grounding_2"
    x_grounding_3 = "x_grounding_3"
    x_grounding_from = "x_grounding_from"
    x_grounding_to = "x_grounding_to"
    x_na = "x_na"
    x_nb = "x_nb"
    x_nc = "x_nc"
    x_nn = "x_nn"
    z01_ratio = "z01_ratio"

    def __repr__(self):
        return self.value

type DatasetTypeLike = DatasetType | str
DatasetTypeVar = TypeVar("DatasetTypeVar", bound=DatasetTypeLike)  # helper used for type deduction

type ComponentTypeLike = ComponentType | str
ComponentTypeVar = TypeVar("ComponentTypeVar", bound=ComponentTypeLike)  # helper used for type deduction

type AttributeTypeLike = AttributeType | str
AttributeTypeVar = TypeVar("AttributeTypeVar", bound=AttributeTypeLike)  # helper used for type deduction


def _str_to_datatype(data_type: DatasetTypeLike) -> DatasetType:
    """Helper function to transform data_type str to DatasetType."""
    if isinstance(data_type, DatasetType):
        return data_type
    return DatasetType[data_type]


def _map_to_datatypes[K: DatasetTypeLike, V](data: Mapping[K, V]) -> dict[DatasetType, V]:
    """Helper function to map datatype str keys to DatasetType."""
    return {_str_to_datatype(key): value for key, value in data.items()}


def _str_to_component_type(component: ComponentTypeLike) -> ComponentType:
    """Helper function to transform component str to ComponentType."""
    if isinstance(component, ComponentType):
        return component
    return ComponentType[component]


def _map_to_component_types[K: ComponentTypeLike, V](data: Mapping[K, V]) -> dict[ComponentType, V]:
    """Helper function to map componenttype str keys to ComponentType."""
    return {_str_to_component_type(key): value for key, value in data.items()}


def _str_to_attribute_type(attribute: AttributeTypeLike) -> AttributeType:
    """Helper function to transform attribute str to AttributeType."""
    if isinstance(attribute, AttributeType):
        return attribute
    return AttributeType[attribute]


def _map_to_attribute_types[K: AttributeTypeLike, V](data: Mapping[K, V]) -> dict[AttributeType, V]:
    """Helper function to map AttributeType str keys to AttributeType."""
    return {_str_to_attribute_type(key): value for key, value in data.items()}

# fmt: on
