import logging
import time
import requests
from functools import wraps

from simple_container_runtime.exceptions import ScrBotoError


def get_logger(root=False):
    logging.basicConfig(format='%(asctime)s %(levelname)s %(name)s: %(message)s',
                        datefmt='%d.%m.%Y %H:%M:%S')
    if root:
        return logging.getLogger('scr')
    else:
        return logging.getLogger('scr.{0}'.format(__name__))


def timed(function):
    logger = logging.getLogger(__name__)

    @wraps(function)
    def wrapper(*args, **kwds):
        start = time.time()
        result = function(*args, **kwds)
        elapsed = time.time() - start
        logger.debug("Execution of {0} required {1}s".format(function.__name__, round(elapsed, 2)))
        return result

    return wrapper


def get_logger(name: str = None, root: bool = False):
    logging.basicConfig(format='%(asctime)s %(levelname)s %(name)s: %(message)s',
                        datefmt='%d.%m.%Y %H:%M:%S')
    if not root and name:
        return logging.getLogger('scr.{0}'.format(name))
    else:
        return logging.getLogger('scr')


def get_instance_id():
    return requests.get('http://169.254.169.254/latest/meta-data/instance-id', timeout=5).text


def with_boto_retry(max_retries=3, pause_time_multiplier=5):
    """
    Annotation retrying a wrapped function call if it raises a CfnSphereBotoError
    with is_throttling_exception=True
    :param max_retries:
    :param pause_time_multiplier:
    :return: :raise e:
    """
    logger = get_logger()

    def decorator(function):
        @wraps(function)
        def wrapper(*args, **kwds):
            retries = 0

            while True:
                try:
                    return function(*args, **kwds)
                except ScrBotoError as e:
                    if not e.is_throttling_exception or retries >= max_retries:
                        raise e

                    sleep_time = pause_time_multiplier * (2 ** retries)
                    logger.warn(
                        "{0} call failed with: '{1}' (Will retry in {2}s)".format(function.__name__, e, sleep_time))
                    time.sleep(sleep_time)
                    retries += 1

        return wrapper

    return decorator

import logging
import time
import requests
from functools import wraps

from simple_container_runtime.exceptions import ScrBotoError


def timed(function):
    logger = logging.getLogger(__name__)

    @wraps(function)
    def wrapper(*args, **kwds):
        start = time.time()
        result = function(*args, **kwds)
        elapsed = time.time() - start
        logger.debug("Execution of {0} required {1}s".format(function.__name__, round(elapsed, 2)))
        return result

    return wrapper


def get_logger(name: str = None, root: bool = False):
    logging.basicConfig(format='%(asctime)s %(levelname)s %(name)s: %(message)s',
                        datefmt='%d.%m.%Y %H:%M:%S')
    if not root and name:
        return logging.getLogger('scr.{0}'.format(name))
    else:
        return logging.getLogger('scr')


def get_instance_id():
    return requests.get('http://169.254.169.254/latest/meta-data/instance-id', timeout=5).text


def with_boto_retry(max_retries=3, pause_time_multiplier=5):
    """
    Annotation retrying a wrapped function call if it raises a CfnSphereBotoError
    with is_throttling_exception=True
    :param max_retries:
    :param pause_time_multiplier:
    :return: :raise e:
    """
    logger = get_logger()

    def decorator(function):
        @wraps(function)
        def wrapper(*args, **kwds):
            retries = 0

            while True:
                try:
                    return function(*args, **kwds)
                except ScrBotoError as e:
                    if not e.is_throttling_exception or retries >= max_retries:
                        raise e

                    sleep_time = pause_time_multiplier * (2 ** retries)
                    logger.warn(
                        "{0} call failed with: '{1}' (Will retry in {2}s)".format(function.__name__, e, sleep_time))
                    time.sleep(sleep_time)
                    retries += 1

        return wrapper

    return decorator

remove duplicate get_logger function