#-*- coding: utf-8 -*-


import datetime
import logging
import os
import time


def singleton(class_):
    instances = {}
    def getinstance(*args, **kwargs):
        if class_ not in instances:
            instances[class_] = class_(*args, **kwargs)
        return instances[class_]
    return getinstance


logging.basicConfig()
logger = logging.getLogger('safe_rsync')

loglevel = os.environ.get('LOGLEVEL', 'INFO')
if loglevel not in ('DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'):
    logger.warn('LOGLEVEL environment variable has wrong value=={}. Using '
                '"INFO" by default.'.format(loglevel))
    loglevel = 'INFO'
logger.setLevel(loglevel)


def logged(logger=None):
    if logger is None:
        logger = globals().get('logger')

    def wrap(f):
        def wrapped_f(*args, **kwargs):
            logger.debug('Starting {}({}, {}) (defaults: {})'
                         ''.format(f.__name__,
                                   str(args),
                                   str(kwargs),
                                   str(f.__defaults__))
                         )
            r = f(*args, **kwargs)
            logger.debug('{} done with result "{}".'.
                         format(f.__name__, str(r)))
            return r
        return wrapped_f
    return wrap


class ResultNotProduced(Exception):
    def __init__(self, value):
        self.value = value

    def __str__(self):
        return repr(self.value)


class Retry(object):
    """
    Waits while the function reaches the specified status.

    :param function: function that returns some status
    :param expected_status: status the machine should turn to
    :param attempts: how many times to check status
    :param timeout: timeout in seconds before attempts
    :return: True if node moves to the specified status, False otherwise
    :Examples:
    Retry(timeout=3, attempts=10).wait(function, result, param1, param2)
    Retry().wait_result(function, result, param1, param2)
    """

    def __init__(self, timeout=5, attempts=10):
        self.timeout = timeout
        self.attempts = attempts
        self.logger = globals().get('logger').getChild('Retry')

    def wait_result(self, function, expected_result, *args, **kwargs):

        self.logger.debug('Wait for {}() == {}...'
                          ''.format(function.__name__, str(expected_result)))

        @logged(self.logger)
        def f():
            return function(*args, **kwargs)

        attempt = 1
        while attempt <= self.attempts:
            try:
                result = f()
            except Exception as e:
                self.logger.error('Exception on function {}: {}'
                                  ''.format(function.__name__, str(e)))
                raise
            else:
                if result == expected_result:
                    self.logger.debug('Got on attempt #{}:'.format(attempt))
                    return result
                attempt += 1
                time.sleep(self.timeout)

        raise ResultNotProduced('Result "{}" was not produced during '
                                '{} attempts.'
                                ''.format(expected_result, attempt - 1))
