import functools
import logging
import time

try:
    import os_client_config
except ImportError:
    os_client_config = None
from salt import exceptions

from keystoneclient import exceptions as ks_exceptions

log = logging.getLogger(__name__)


class KeystoneException(Exception):

    _msg = "Keystone module exception occured."

    def __init__(self, message=None, **kwargs):
        super(KeystoneException, self).__init__(message or self._msg)


class NoKeystoneEndpoint(KeystoneException):
    _msg = "Keystone endpoint not found in keystone catalog."


class NoAuthPluginConfigured(KeystoneException):
    _msg = ("You are using keystoneauth auth plugin that does not support "
            "fetching endpoint list from token (noauth or admin_token).")


class NoCredentials(KeystoneException):
    _msg = "Please provide cloud name present in clouds.yaml."


class ResourceNotFound(KeystoneException):
    _msg = "Uniq resource: {resource} with name: {name} not found."

    def __init__(self, resource, name, **kwargs):
        super(KeystoneException, self).__init__(
            self._msg.format(resource=resource, name=name))


class MultipleResourcesFound(KeystoneException):
    _msg = "Multiple resource: {resource} with name: {name} found."

    def __init__(self, resource, name, **kwargs):
        super(KeystoneException, self).__init__(
            self._msg.format(resource=resource, name=name))


def _get_raw_client(cloud_name):
    if not os_client_config:
        raise exceptions.SaltInvocationError(
            "Cannot load os-client-config. Please check your environment "
            "configuration.")
    service_type = 'identity'
    config = os_client_config.OpenStackConfig()
    cloud = config.get_one_cloud(cloud_name)
    adapter = cloud.get_session_client(service_type)
    adapter.version = '3'
    try:
        access_info = adapter.session.auth.get_access(adapter.session)
        endpoints = access_info.service_catalog.get_endpoints()
    except (AttributeError, ValueError):
        e = NoAuthPluginConfigured()
        log.exception('%s' % e)
        raise e
    if service_type not in endpoints:
        if not service_type:
            e = NoKeystoneEndpoint()
            log.error('%s' % e)
            raise e
    return adapter


def send(method, microversion_header=None):
    def wrap(func):
        @functools.wraps(func)
        def wrapped_f(*args, **kwargs):
            headers = kwargs.pop('headers', {})
            if kwargs.get('microversion'):
                headers.setdefault(microversion_header,
                                   kwargs.get('microversion'))
            cloud_name = kwargs.pop('cloud_name')
            connect_retries = 30
            connect_retry_delay = 1
            if not cloud_name:
                e = NoCredentials()
                log.error('%s' % e)
                raise e
            adapter = None
            for i in range(connect_retries):
              try:
                adapter = _get_raw_client(cloud_name)
              except (ks_exceptions.DiscoveryFailure) as e:
                msg = ("Got exception when determining a suitable "
                       "URL for Keystone plugin. Sleeping for %ss. Attepmpts "
                       "%s of %s")
                log.error(msg % (connect_retry_delay, i, connect_retries))
                time.sleep(connect_retry_delay)
                continue
              break
            if not adapter:
              raise ks_exceptions.DiscoveryFailure("Could not connect to Keystone API to determine a suitable URL for the plugin")
            # Remove salt internal kwargs
            kwarg_keys = list(kwargs.keys())
            for k in kwarg_keys:
                if k.startswith('__'):
                    kwargs.pop(k)
            url, json  = func(*args, **kwargs)
            response = None
            last_exception = None
            for i in range(connect_retries):
                try:
                  response = getattr(adapter, method)(
                      url, connect_retries=connect_retries,
                      json=json)
                except Exception as e:
                    last_exception = e
                    if not hasattr(e, 'http_status') or (e.http_status >= 500
                        or e.http_status == 0):
                        msg = ("Got retriable exception when contacting "
                               "Keystone API. Sleeping for %ss. Attepmpts "
                               "%s of %s")
                        log.error(msg % (connect_retry_delay, i, connect_retries))
                        time.sleep(connect_retry_delay)
                        continue
                    else:
                        break
                else:
                   last_exception = None
                   break
            if last_exception:
                raise KeystoneException(last_exception.message)
            if not response or not response.content:
                return {}
            try:
                resp = response.json()
            except ValueError:
                resp = response.content
            return resp
        return wrapped_f
    return wrap
