import imp
import os
from textwrap import dedent
from requests.exceptions import BaseHTTPError, RequestException

import logging

logger = logging.getLogger(__name__)


def default_config_path():
    return os.path.expanduser(u'~/.chacractl')


def get_config_path():
    """
    Return the .chacractl configuration location
    """
    config = default_config_path()
    if os.path.exists(config):
        return config


def load_config():
    config = get_config_path()
    if not config:
        return
    return imp.load_source('chacractl', config)


def ensure_default_config():
    """
    Create a default config if the config file does not currently exist
    """
    template = dedent("""
    # This file was automatically generated by the chacractl CLI
    # make sure to update it with the correct user and key to talk to the API
    url = "http://example"
    user = "chacra user"
    key = "secret"
    ssl_verify = True
    """)
    config = default_config_path()
    if not os.path.exists(config):
        with open(config, 'w') as f:
            f.write(template)

import functools
import time

def retry(exceptions=(RequestException, BaseHTTPError), delay=5, times=3):
    """
    A decorator for retrying a function call with a specified delay in case of a set of exceptions, mainly
    intended to avoid the *horrendous* requests lacking API to deal with this.

    :param exceptions:  A tuple of all exceptions that need to be caught for retry
                                        e.g. retry(exception_list = (Timeout, Readtimeout))
    :param delay: Amount of delay (seconds) needed between successive retries.
    :param times: no of times the function should be retried
    """
    def outer_wrapper(function):
        @functools.wraps(function)
        def inner_wrapper(*args, **kwargs):
            final_excep = None
            for counter in xrange(times):
                if counter > 0:
                    time.sleep(delay)
                final_excep = None
                try:
                    value = function(*args, **kwargs)
                    return value
                except (exceptions) as e:
                    final_excep = e
                    if hasattr(e, 'response'):
                        if hasattr(e.response, 'status_code'):
                            status = e.response.status_code
                            if status < 500:
                                raise
                    logger.warning('while trying a request, got an exception: %s', str(e))
                    pass

            if final_excep is not None:
                raise final_excep
        return inner_wrapper

    return outer_wrapper
