from __future__ import annotations


from sqlglot import exp, generator, transforms
from sqlglot.dialects.dialect import rename_func, strposition_sql as _strposition_sql


class TableauGenerator(generator.Generator):
    SELECT_KINDS: tuple[str, ...] = ()
    TRY_SUPPORTED = False
    SUPPORTS_UESCAPE = False
    SUPPORTS_DECODE_CASE = False

    AFTER_HAVING_MODIFIER_TRANSFORMS = generator.AFTER_HAVING_MODIFIER_TRANSFORMS

    JOIN_HINTS = False
    TABLE_HINTS = False
    QUERY_HINTS = False

    TRANSFORMS = {
        **generator.Generator.TRANSFORMS,
        exp.Coalesce: rename_func("IFNULL"),
        exp.Select: transforms.preprocess([transforms.eliminate_distinct_on]),
    }

    PROPERTIES_LOCATION = {
        **generator.Generator.PROPERTIES_LOCATION,
        exp.VolatileProperty: exp.Properties.Location.UNSUPPORTED,
    }

    def if_sql(self, expression: exp.If) -> str:
        this = self.sql(expression, "this")
        true = self.sql(expression, "true")
        false = self.sql(expression, "false")
        return f"IF {this} THEN {true} ELSE {false} END"

    def count_sql(self, expression: exp.Count) -> str:
        this = expression.this
        if isinstance(this, exp.Distinct):
            return self.func("COUNTD", *this.expressions)
        return self.func("COUNT", this)

    def strposition_sql(self, expression: exp.StrPosition) -> str:
        has_occurrence = "occurrence" in expression.args
        return _strposition_sql(
            self,
            expression,
            func_name="FINDNTH" if has_occurrence else "FIND",
            supports_occurrence=has_occurrence,
        )
