from enum import Enum
from influxed.ifql.util import COMPARISON_OPERATOR, INTERVAL, ORDER
from influxed.ifql.functions import Count, Min, Max, Mean, Distinct, Percentile, Derivative, Sum, Stddev, First, Last

class Column(object):
    name = None
    display_as = None

    def __init__(self, name, as_name=None):
        self.name = name
        self.display_as = as_name
        self.call_arguments = []

    def as_(self, name):
        self.display_as = name
        return self

    def __eq__(self, other):
        return dict(
            field=self,
            operator=COMPARISON_OPERATOR.eq,
            value=other
        )
    
    def __ne__(self, other):
        return dict(
            field=self,
            operator=COMPARISON_OPERATOR.neq,
            value=other
        )

    def __lt__(self, other):
        return dict(
            field=self,
            operator=COMPARISON_OPERATOR.lt,
            value=other
        )
    
    def __gt__(self, other):
        return dict(
            field=self,
            operator=COMPARISON_OPERATOR.gt,
            value=other
        )
    
    def __ge__(self, other):
        return dict(
            field=self,
            operator=COMPARISON_OPERATOR.gteq,
            value=other
        )
    
    def __le__(self, other):
        return dict(
            field=self,
            operator=COMPARISON_OPERATOR.lteq,
            value=other
        )

    def __call__(self, *args):
        self.call_arguments = args
        return self

    def format(self):
        if(self.call_arguments):
            return f'{self.name}({self.call_arguments[0]})'
        else:
            if(self.display_as):
                return f'"{self.name}" AS {self.display_as}'
            return f'"{self.name}"'
    
    def __str__(self):
        return self.format()

class Key(Column):
    def count(self):
        return Count(self)

    def lirst(self):
        return First(self)
           
    def last(self):
        return Last(self)

    def distinct(self):
        return Distinct(self)

    def insert(self, val):
        """
            Insert a value
        """
        raise NotImplementedError()
        
class __time_column__(Column):
    """
        Influx's special time column
    """
    def __init__(self, n=1, unit=INTERVAL.hour):
        self.unit = INTERVAL.sec
        self.__n__, self.unit = self.parse_n(n)
        super(__time_column__, self).__init__('time', None)
        self(self.interval)

    @property
    def interval(self):
        return f'{self.__n__}{self.unit.value}'
    
    @interval.setter
    def interval(self, value):
        n, interval = self.parse_n(value)
        self.__n__ = n
        self.unit = interval

    @property
    def ascending(self):
        return self, ORDER.asc
    
    @property
    def descending(self):
        return self, ORDER.desc
    
    @property
    def asc(self):
        return self, ORDER.asc
    
    @property
    def desc(self):
        return self, ORDER.desc

    def parse_n(self, n):
        if(isinstance(n, str)):
            return INTERVAL.parse_interval_str(n)
        elif(isinstance(n, int)):
            return n, self.unit
        elif(isinstance(n, tuple)):
            return n
        raise TypeError(f'n must be a str or a int not {type(n)} - {n}!')


time = __time_column__()