import logging
import os_client_config
import functools
import time

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):
    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
