import time
import logging
import random
from functools import wraps

# [Note] https://qiita.com/msi/items/0fcb6a9947770528e539


class Timer:
    def __init__(self, gamma=0.99, sample_interval=100, print_interval=1000):
        self.avg_time = None
        self.gamma = gamma
        self.sample_interval = sample_interval
        self.print_interval = print_interval
        self.cnt = 0
        self.start = None

    def __call__(self, func):
        @wraps(func)
        def new_func(*args, **kwargs):
            start = time.perf_counter()
            ret = func(*args, **kwargs)
            self.cnt += 1
            if self.cnt % self.sample_interval == 0:
                elapsed_time = time.perf_counter() - start
                self.avg_time = \
                    (1 - self.gamma)*elapsed_time + self.gamma * self.avg_time \
                    if (self.avg_time is not None) else elapsed_time
            if self.cnt % self.print_interval == 0:
                txt = f'elapsed time by function {self.__name__}: {self.avg_time}'
                logging.debug(txt)
            return ret

        setattr(self, "__name__", new_func.__name__)
        setattr(self, "__doc__", new_func.__doc__)
        return new_func


if __name__ == '__main__':
    # test code

    @Timer(sample_interval=1, print_interval=1)
    def wait():
        time.sleep(random.random()/10)

    logging.basicConfig(level=logging.DEBUG)
    while True:
        wait()


