#  Copyright (C) 2023
#  ABM, Moscow
#
#  UNPUBLISHED PROPRIETARY MATERIAL.
#  ALL RIGHTS RESERVED.
#
#  Authors: Mike Orlov <m.orlov@abm-jsc.ru>
from dataclasses import dataclass

from entity_read import sql
from entity_read.entity import Entity
from entity_read.sql.atoms import Selectable
from .expression import Expression

key_to_function_factory = {
    "lt": sql.inter.FunctionLessThan,
    "le": sql.inter.FunctionLessEqual,
    "eq": sql.inter.FunctionEqual,
    "ne": sql.inter.FunctionNonEqual,
    "ge": sql.inter.FunctionGreaterEqual,
    "gt": sql.inter.FunctionGreater,
    "in": sql.inter.FunctionIn,
    "not_in": sql.inter.FunctionNotIn,
    "or": sql.inter.FunctionOr,
    "and": sql.inter.FunctionAnd,
    "not": sql.inter.FunctionNot,
    "like": lambda args: sql.inter.FunctionStringContains(
        args=(sql.inter.FunctionCastToStr(args=args[:1]), args[1]), ignore_case=False),
    "ilike": lambda args: sql.inter.FunctionStringContains(
        args=(sql.inter.FunctionCastToStr(args=args[:1]), args[1]), ignore_case=True),
    "is_null": sql.inter.FunctionIsNull,
    "is_not_null": sql.inter.FunctionIsNotNull,
}


@dataclass(frozen=True, kw_only=True, repr=False)
class Condition(Expression):
    key: str
    args: list[Expression]

    def eval(self, entity_type: type[Entity], variables: dict[str, Selectable]) -> sql.atoms.function.Function:
        if (function_factory := key_to_function_factory.get(self.key)) is None:
            raise KeyError(f"Not found condition {self.key!r}")
        # noinspection PyArgumentList
        return function_factory(args=[arg.eval(entity_type, variables) for arg in self.args])

    def shortcut(self) -> str:
        return f"cond.{self.key}({','.join([arg.shortcut() for arg in self.args])})"
