from operator import attrgetter
from typing import Callable, Dict, Type

from .proto.qlik.sse import DataType, Dual


def map_data_type(t: Type) -> DataType:
    if t is str:
        return DataType.STRING
    if t is float:
        return DataType.NUMERIC
    return DataType.DUAL


py_to_data_type = {
    str: DataType.STRING,
    float: DataType.NUMERIC,
    Dual: DataType.DUAL,
}


def to_dual(value: str | float) -> Dual:
    if isinstance(value, str):
        return Dual(str_data=value)
    return Dual(num_data=float(value))


def from_dual(dual: Dual, data_type: DataType) -> str | float | None:
    if data_type == DataType.STRING:
        return dual.str_data
    elif data_type == DataType.NUMERIC or dual.num_data is not None:
        return dual.num_data
    return dual.str_data


dual_getters: Dict[DataType, Callable[[Dual], str | float | Dual]] = {
    DataType.STRING: attrgetter("str_data"),
    DataType.NUMERIC: attrgetter("num_data"),
    DataType.DUAL: lambda d: d,
}
