import os
import time
from . import decorators_lua


def max_sim_execs():
    '''
        Decorator to limit concurrents executions of the same method.
        Args:
            param1(string): key to limit.
            param2(int): maximun number of concurrents executions.
            param3(redis): reids instance.
            param4(int): windows size. (optional)
        Returns:
            int: 0 or 1. if returns 1 the method has to wait, when returns 0 the methos continues.
    '''
    '''

    Example:
        @max_sim_execs('estemetodo', 2, r)
    '''
    def p_decorate(func):
        def func_wrapper(*args, **kwargs):
            try:
                key, limit, redis, limit_time = args[0]._get_decorator_params()
            except:
                key = kwargs.pop('key', 'MAX_SIM_EXEC')
                limit = kwargs.pop('limit', 0)
                redis = kwargs.pop('redis', None)
                limit_time = kwargs.pop('limit_time', 300)
            result = False
            if redis and limit > 0:
                subkey = '{0}.{1}'.format(int(time.time() * 1000000), str(os.getpid()))
                srl = decorators_lua.StoneMRL(redis)
                reason = 1
                while reason:
                    now = int(time.time())
                    reason = srl.callRL(key, subkey, limit, limit_time, now)
                    time.sleep(0.01)

                if reason == 0:
                    try:
                        result = func(*args, **kwargs)
                    except:
                        result = False
                redis.zrem(key, subkey)
            else:
                result = func(*args, **kwargs)
            return result
        return func_wrapper
    return p_decorate
