# -*- coding: utf-8 -*-
'''
Module for handling openstack keystone calls.

:optdepends:    - keystoneclient Python adapter
:configuration: This module is not usable until the following are specified
    either in a pillar or in the minion's config file:

    .. code-block:: yaml

        keystone.user: admin
        keystone.password: verybadpass
        keystone.tenant: admin
        keystone.tenant_id: f80919baedab48ec8931f200c65a50df
        keystone.auth_url: 'http://127.0.0.1:5000/v2.0/'

    OR (for token based authentication)

    .. code-block:: yaml

        keystone.token: 'ADMIN'
        keystone.endpoint: 'http://127.0.0.1:35357/v2.0'

    If configuration for multiple openstack accounts is required, they can be
    set up as different configuration profiles. For example:

    .. code-block:: yaml

        openstack1:
          keystone.user: admin
          keystone.password: verybadpass
          keystone.tenant: admin
          keystone.tenant_id: f80919baedab48ec8931f200c65a50df
          keystone.auth_url: 'http://127.0.0.1:5000/v2.0/'

        openstack2:
          keystone.user: admin
          keystone.password: verybadpass
          keystone.tenant: admin
          keystone.tenant_id: f80919baedab48ec8931f200c65a50df
          keystone.auth_url: 'http://127.0.0.2:5000/v2.0/'

        openstack_version3:
          keystone.user: admin
          keystone.password: verybadpass
          keystone.tenant: admin
          keystone.tenant_id: f80919baedab48ec8931f200c65a50df
          keystone.auth_url: 'http://127.0.0.2:5000/v3'

        openstack_nonversioned:
          keystone.user: admin
          keystone.password: verybadpass
          keystone.tenant: admin
          keystone.tenant_id: f80919baedab48ec8931f200c65a50df
          keystone.auth_url: 'http://127.0.0.2:5000'

    With this configuration in place, any of the keystone functions can make use
    of a configuration profile by declaring it explicitly.
    For example:

    .. code-block:: bash

        salt '*' keystone.tenant_list profile=openstack1
'''

# Import Python libs
from __future__ import absolute_import
import logging

# Import Salt Libs
import salt.utils.http

# Import 3rd-party libs
from salt.ext import six
HAS_KEYSTONE = False
try:
    # pylint: disable=import-error
    from keystoneclient import client
    from keystoneclient.v2_0 import client as keystoneclient_v2
    import keystoneclient.exceptions
    HAS_KEYSTONE = True
    from keystoneclient.v3 import client as keystoneclient_v3
    from keystoneclient import discover
    from keystoneauth1 import session
    from keystoneauth1.identity import generic
    from keystoneauth1 import token_endpoint
    # pylint: enable=import-error
except ImportError:
    pass

log = logging.getLogger(__name__)


def __virtual__():
    '''
    Only load this module if keystone
    is installed on this minion.
    '''
    if HAS_KEYSTONE:
        return 'keystoneng'
    return (False, 'keystone execution module cannot be loaded: keystoneclient python library not available.')

__opts__ = {}


def _get_kwargs(profile=None, **connection_args):
    '''
    get connection args
    '''
    if profile:
        prefix = profile + ":keystone."
    else:
        prefix = "keystone."

    def get(key, default=None):
        '''
        look in connection_args first, then default to config file
        '''
        return connection_args.get('connection_' + key,
                                   __salt__['config.get'](prefix + key, default))

    user = get('user', 'admin')
    password = get('password', 'ADMIN')
    tenant = get('tenant', 'admin')
    tenant_id = get('tenant_id')
    auth_url = get('auth_url', 'http://127.0.0.1:5000/v2.0/')
    insecure = get('insecure', False)
    token = get('token')
    endpoint = get('endpoint', 'http://127.0.0.1:5000/v2.0')
    if token:
        kwargs = {'token': token,
                  'endpoint': endpoint}
    else:
        kwargs = {'username': user,
                  'password': password,
                  'tenant_name': tenant,
                  'tenant_id': tenant_id,
                  'auth_url': auth_url}
        # 'insecure' keyword not supported by all v2.0 keystone clients
        #   this ensures it's only passed in when defineda
        if get('user_id'): kwargs['user_id']=get('user_id')
        if get('user_domain_id'): kwargs['user_domain_id']=get('user_domain_id')
        if get('domain_id'): kwargs['domain_id']=get('domain_id')
        if get('domain_name'): kwargs['domain_name']=get('domain_name')
        if get('project_id'): kwargs['project_id']=get('project_id')
        if get('project_name'): kwargs['project_name']=get('project_name')
        if get('project_domain_id'): kwargs['project_domain_id']=get('project_domain_id')
        if get('region_name'): kwargs['region_name']=get('region_name')
        if get('endpoint'): kwargs['endpoint']=get('endpoint')
        if get('timeout'): kwargs['timeout']=get('timeout')
        if get('user_domain_name'): kwargs['user_domain_name']=get('user_domain_name')
        if get('project_domain_name'): kwargs['project_domain_name']=get('project_domain_name')
        kwargs['insecure'] = get('insecure', False)
        if get('version'):
            version_list = str(get('version')).split('.')
            if len(version_list) == 2:
                kwargs['version'] = (version_list[0], version_list[1])
            else:
                kwargs['version'] = (version_list[0])

    return kwargs


def _client_version(keystone_client):
    '''
    Returns keystone client version
    '''
    if isinstance(keystone_client, keystoneclient_v3.Client):
        return 3
    if isinstance(keystone_client, keystoneclient_v2.Client):
        return 2
    return None


def _project_mgr(keystone_client):
    '''
    Returns keystoneclient.v3.Client.projects object if keystone client version > 2
    or keystoneclient.v2_0.Client.tenants for other cases.
    '''
    if _client_version(keystone_client) > 2:
        return keystone_client.projects
    return keystone_client.tenants


def api_version(profile=None, **connection_args):
    '''
    Returns the API version derived from endpoint's response.

    CLI Example:

    .. code-block:: bash

        salt '*' keystone.api_version
    '''
    keystone_client = auth(profile, **connection_args)
    if isinstance(keystone_client, keystoneclient_v3.Client):
        return 3
    if isinstance(keystone_client, keystoneclient_v2.Client):
        return 2
    return None


def auth(profile=None, **connection_args):
    '''
    Set up keystone credentials. Only intended to be used within Keystone-enabled modules.

    CLI Example:

    .. code-block:: bash

        salt '*' keystone.auth
    '''
    kwargs = _get_kwargs(profile=profile, **connection_args)
    if 'token' in kwargs:
        auth = token_endpoint.Token(endpoint=kwargs['endpoint'], token=kwargs['token'])
    else:
        # keystoneauth1 Password class does not accept some args. Therefore remove it from args for auth.
        auth_connection_args=kwargs.copy()
        auth_connection_args.pop('region_name', None)
        auth_connection_args.pop('version', None)
        auth_connection_args.pop('insecure', None)
        auth = generic.Password(**auth_connection_args)
    if 'insecure' in kwargs:
         certs_verify = False
    else:
        certs_verify = True
    sess = session.Session(auth=auth, verify=certs_verify)
    keystone_client=client.Client(session=sess, **kwargs)
    return keystone_client


def ec2_credentials_create(user_id=None, name=None,
                           tenant_id=None, tenant=None,
                           profile=None, **connection_args):
    '''
    Create EC2-compatible credentials for user per tenant

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.ec2_credentials_create name=admin tenant=admin

        salt '*' keystone.ec2_credentials_create \
        user_id=c965f79c4f864eaaa9c3b41904e67082 \
        tenant_id=722787eb540849158668370dc627ec5f
    '''
    kstone = auth(profile, **connection_args)

    if name:
        user_id = user_get(name=name, profile=profile,
                           **connection_args)[name]['id']
    if not user_id:
        return {'Error': 'Could not resolve User ID'}

    if tenant:
        tenant_id = tenant_get(name=tenant, profile=profile,
                               **connection_args)[tenant]['id']
    if not tenant_id:
        return {'Error': 'Could not resolve Tenant ID'}

    newec2 = kstone.ec2.create(user_id, tenant_id)
    return {'access': newec2.access,
            'secret': newec2.secret,
            'tenant_id': newec2.tenant_id,
            'user_id': newec2.user_id}


def ec2_credentials_delete(user_id=None, name=None, access_key=None,
                           profile=None, **connection_args):
    '''
    Delete EC2-compatible credentials

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.ec2_credentials_delete \
        860f8c2c38ca4fab989f9bc56a061a64 access_key=5f66d2f24f604b8bb9cd28886106f442

        salt '*' keystone.ec2_credentials_delete name=admin \
        access_key=5f66d2f24f604b8bb9cd28886106f442
    '''
    kstone = auth(profile, **connection_args)

    if name:
        user_id = user_get(name=name, profile=None, **connection_args)[name]['id']
    if not user_id:
        return {'Error': 'Could not resolve User ID'}
    kstone.ec2.delete(user_id, access_key)
    return 'ec2 key "{0}" deleted under user id "{1}"'.format(access_key,
                                                              user_id)


def ec2_credentials_get(user_id=None, name=None, access=None,
                        profile=None, **connection_args):
    '''
    Return ec2_credentials for a user (keystone ec2-credentials-get)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.ec2_credentials_get c965f79c4f864eaaa9c3b41904e67082 access=722787eb540849158668370
        salt '*' keystone.ec2_credentials_get user_id=c965f79c4f864eaaa9c3b41904e67082 access=722787eb540849158668370
        salt '*' keystone.ec2_credentials_get name=nova access=722787eb540849158668370dc627ec5f
    '''
    kstone = auth(profile, **connection_args)
    ret = {}
    if name:
        for user in kstone.users.list():
            if user.name == name:
                user_id = user.id
                break
    if not user_id:
        return {'Error': 'Unable to resolve user id'}
    if not access:
        return {'Error': 'Access key is required'}
    ec2_credentials = kstone.ec2.get(user_id=user_id, access=access,
                                     profile=profile, **connection_args)
    ret[ec2_credentials.user_id] = {'user_id': ec2_credentials.user_id,
                                    'tenant': ec2_credentials.tenant_id,
                                    'access': ec2_credentials.access,
                                    'secret': ec2_credentials.secret}
    return ret


def ec2_credentials_list(user_id=None, name=None, profile=None,
                         **connection_args):
    '''
    Return a list of ec2_credentials for a specific user (keystone ec2-credentials-list)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.ec2_credentials_list 298ce377245c4ec9b70e1c639c89e654
        salt '*' keystone.ec2_credentials_list user_id=298ce377245c4ec9b70e1c639c89e654
        salt '*' keystone.ec2_credentials_list name=jack
    '''
    kstone = auth(profile, **connection_args)
    ret = {}
    if name:
        for user in kstone.users.list():
            if user.name == name:
                user_id = user.id
                break
    if not user_id:
        return {'Error': 'Unable to resolve user id'}
    for ec2_credential in kstone.ec2.list(user_id):
        ret[ec2_credential.user_id] = {'user_id': ec2_credential.user_id,
                                       'tenant_id': ec2_credential.tenant_id,
                                       'access': ec2_credential.access,
                                       'secret': ec2_credential.secret}
    return ret


def endpoint_get(service, region=None, profile=None, interface=None, **connection_args):
    '''
    Return a specific endpoint (keystone endpoint-get)

    CLI Example:

    .. code-block:: bash

        salt 'v2' keystone.endpoint_get nova [region=RegionOne]

        salt 'v3' keystone.endpoint_get nova interface=admin [region=RegionOne]
    '''
    auth(profile, **connection_args)
    services = service_list(profile, **connection_args)
    if service not in services:
        return {'Error': 'Could not find the specified service'}
    service_id = services[service]['id']
    endpoints = endpoint_list(profile, **connection_args)

    e = [_f for _f in [e
          if e['service_id'] == service_id and
            (e['region'] == region if region else True) and
            (e['interface'] == interface if interface else True)
            else None for e in endpoints.values()] if _f]
    if len(e) > 1:
        return {'Error': 'Multiple endpoints found ({0}) for the {1} service. Please specify region.'.format(e, service)}
    if len(e) == 1:
        return e[0]
    return {'Error': 'Could not find endpoint for the specified service'}


def endpoint_list(profile=None, **connection_args):
    '''
    Return a list of available endpoints (keystone endpoints-list)

    CLI Example:

    .. code-block:: bash

        salt '*' keystone.endpoint_list
    '''
    kstone = auth(profile, **connection_args)
    ret = {}

    for endpoint in kstone.endpoints.list():
        ret[endpoint.id] = dict((value, getattr(endpoint, value)) for value in dir(endpoint)
                                if not value.startswith('_') and
                                isinstance(getattr(endpoint, value), (six.string_types, dict, bool)))
    return ret


def endpoint_create(service, publicurl=None, internalurl=None, adminurl=None,
                    region=None, profile=None, url=None, interface=None, **connection_args):
    '''
    Create an endpoint for an Openstack service

    CLI Examples:

    .. code-block:: bash

        salt 'v2' keystone.endpoint_create nova 'http://public/url' 'http://internal/url' 'http://adminurl/url' region

        salt 'v3' keystone.endpoint_create nova url='http://public/url' interface='public' region='RegionOne'
    '''
    kstone = auth(profile, **connection_args)
    keystone_service = service_get(name=service, profile=profile,
                                   **connection_args)
    if not keystone_service or 'Error' in keystone_service:
        return {'Error': 'Could not find the specified service'}

    if _client_version(kstone) > 2:
        kstone.endpoints.create(service=keystone_service[service]['id'],
                                region_id=region,
                                url=url,
                                interface=interface)
    else:
        kstone.endpoints.create(region=region,
                                service_id=keystone_service[service]['id'],
                                publicurl=publicurl,
                                adminurl=adminurl,
                                internalurl=internalurl)
    return endpoint_get(service, region, profile, interface, **connection_args)


def endpoint_delete(service, region=None, profile=None, interface=None, **connection_args):
    '''
    Delete endpoints of an Openstack service

    CLI Examples:

    .. code-block:: bash

        salt 'v2' keystone.endpoint_delete nova [region=RegionOne]

        salt 'v3' keystone.endpoint_delete nova interface=admin [region=RegionOne]
    '''
    kstone = auth(profile, **connection_args)
    endpoint = endpoint_get(service, region, profile, interface, **connection_args)
    if not endpoint or 'Error' in endpoint:
        return {'Error': 'Could not find any endpoints for the service'}
    kstone.endpoints.delete(endpoint['id'])
    endpoint = endpoint_get(service, region, profile, interface, **connection_args)
    if not endpoint or 'Error' in endpoint:
        return True


def role_create(name, profile=None, **connection_args):
    '''
    Create a named role.

    CLI Example:

    .. code-block:: bash

        salt '*' keystone.role_create admin
    '''

    kstone = auth(profile, **connection_args)
    if 'Error' not in role_get(name=name, profile=profile, **connection_args):
        return {'Error': 'Role "{0}" already exists'.format(name)}
    kstone.roles.create(name)
    return role_get(name=name, profile=profile, **connection_args)


def role_delete(role_id=None, name=None, profile=None,
                **connection_args):
    '''
    Delete a role (keystone role-delete)


    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.role_delete c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.role_delete role_id=c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.role_delete name=admin
    '''
    kstone = auth(profile, **connection_args)

    if name:
        for role in kstone.roles.list():
            if role.name == name:
                role_id = role.id
                break
    if not role_id:
        return {'Error': 'Unable to resolve role id'}

    role = kstone.roles.get(role_id)
    kstone.roles.delete(role)

    ret = 'Role ID {0} deleted'.format(role_id)
    if name:
        ret += ' ({0})'.format(name)
    return ret


def role_get(role_id=None, name=None, profile=None, **connection_args):
    '''
    Return a specific roles (keystone role-get)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.role_get c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.role_get role_id=c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.role_get name=nova
    '''
    kstone = auth(profile, **connection_args)
    ret = {}
    if name:
        for role in kstone.roles.list():
            if role.name == name:
                role_id = role.id
                break
    if not role_id:
        return {'Error': 'Unable to resolve role id'}
    role = kstone.roles.get(role_id)

    ret[role.name] = {'id': role.id,
                      'name': role.name}
    return ret


def role_list(profile=None, **connection_args):
    '''
    Return a list of available roles (keystone role-list)

    CLI Example:

    .. code-block:: bash

        salt '*' keystone.role_list
    '''
    kstone = auth(profile, **connection_args)
    ret = {}
    for role in kstone.roles.list():
        ret[role.name] = dict((value, getattr(role, value)) for value in dir(role)
                              if not value.startswith('_') and
                              isinstance(getattr(role, value), (six.string_types, dict, bool)))
    return ret


def service_create(name, service_type, description=None, profile=None,
                   **connection_args):
    '''
    Add service to Keystone service catalog

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.service_create nova compute \
'OpenStack Compute Service'
    '''
    kstone = auth(profile, **connection_args)
    service = kstone.services.create(name, service_type, description=description)
    return service_get(service.id, profile=profile, **connection_args)


def service_delete(service_id=None, name=None, profile=None, **connection_args):
    '''
    Delete a service from Keystone service catalog

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.service_delete c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.service_delete name=nova
    '''
    kstone = auth(profile, **connection_args)
    if name:
        service_id = service_get(name=name, profile=profile,
                                 **connection_args)[name]['id']
    kstone.services.delete(service_id)
    return 'Keystone service ID "{0}" deleted'.format(service_id)


def service_get(service_id=None, name=None, profile=None, **connection_args):
    '''
    Return a specific services (keystone service-get)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.service_get c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.service_get service_id=c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.service_get name=nova
    '''
    kstone = auth(profile, **connection_args)
    ret = {}
    if name:
        for service in kstone.services.list():
            if service.name == name:
                service_id = service.id
                break
    if not service_id:
        return {'Error': 'Unable to resolve service id'}
    service = kstone.services.get(service_id)
    ret[service.name] = dict((value, getattr(service, value)) for value in dir(service)
                             if not value.startswith('_') and
                             isinstance(getattr(service, value), (six.string_types, dict, bool)))
    return ret


def service_list(profile=None, **connection_args):
    '''
    Return a list of available services (keystone services-list)

    CLI Example:

    .. code-block:: bash

        salt '*' keystone.service_list
    '''
    kstone = auth(profile, **connection_args)
    ret = {}
    for service in kstone.services.list():
        ret[service.name] = dict((value, getattr(service, value)) for value in dir(service)
                                 if not value.startswith('_') and
                                 isinstance(getattr(service, value), (six.string_types, dict, bool)))
    return ret


def tenant_create(name, description=None, enabled=True, profile=None,
                  **connection_args):
    '''
    Create a keystone tenant

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.tenant_create nova description='nova tenant'
        salt '*' keystone.tenant_create test enabled=False
    '''
    kstone = auth(profile, **connection_args)
    new = _project_mgr(kstone).create(name, description, enabled)
    return tenant_get(new.id, profile=profile, **connection_args)


def project_create(name, domain, description=None, enabled=True, profile=None,
                   **connection_args):
    '''
    Create a keystone project.
    Overrides keystone tenant_create form api V2. For keystone api V3.

    .. versionadded:: 2016.11.0

    name
        The project name, which must be unique within the owning domain.

    domain
        The domain name.

    description
        The project description.

    enabled
        Enables or disables the project.

    profile
        Configuration profile - if configuration for multiple openstack accounts required.

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.project_create nova default description='Nova Compute Project'
        salt '*' keystone.project_create test default enabled=False
    '''
    kstone = auth(profile, **connection_args)
    new = _project_mgr(kstone).create(name=name, domain=domain,
                                                 description=description, enabled=enabled)
    return tenant_get(new.id, profile=profile, **connection_args)


def tenant_delete(tenant_id=None, name=None, profile=None, **connection_args):
    '''
    Delete a tenant (keystone tenant-delete)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.tenant_delete c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.tenant_delete tenant_id=c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.tenant_delete name=demo
    '''
    kstone = auth(profile, **connection_args)
    if name:
        for tenant in _project_mgr(kstone).list():
            if tenant.name == name:
                tenant_id = tenant.id
                break
    if not tenant_id:
        return {'Error': 'Unable to resolve tenant id'}
    _project_mgr(kstone).delete(tenant_id)
    ret = 'Tenant ID {0} deleted'.format(tenant_id)
    if name:

        ret += ' ({0})'.format(name)
    return ret


def project_delete(project_id=None, name=None, profile=None, **connection_args):
    '''
    Delete a project (keystone project-delete).
    Overrides keystone tenant-delete form api V2. For keystone api V3 only.

    .. versionadded:: 2016.11.0

    project_id
        The project id.

    name
        The project name.

    profile
        Configuration profile - if configuration for multiple openstack accounts required.

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.project_delete c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.project_delete project_id=c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.project_delete name=demo
    '''
    kstone = auth(profile, **connection_args)

    if _client_version(kstone) > 2:
        return tenant_delete(tenant_id=project_id, name=name, profile=None, **connection_args)
    else:
        return False


def tenant_get(tenant_id=None, name=None, profile=None,
               **connection_args):
    '''
    Return a specific tenants (keystone tenant-get)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.tenant_get c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.tenant_get tenant_id=c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.tenant_get name=nova
    '''
    kstone = auth(profile, **connection_args)
    ret = {}

    if name:
        for tenant in _project_mgr(kstone).list():
            if tenant.name == name:
                tenant_id = tenant.id
                break
    if not tenant_id:
        return {'Error': 'Unable to resolve tenant id'}
    tenant = _project_mgr(kstone).get(tenant_id)
    ret[tenant.name] = dict((value, getattr(tenant, value)) for value in dir(tenant)
                            if not value.startswith('_') and
                            isinstance(getattr(tenant, value), (six.string_types, dict, bool)))
    return ret


def project_get(project_id=None, name=None, profile=None, **connection_args):
    '''
    Return a specific projects (keystone project-get)
    Overrides keystone tenant-get form api V2.
    For keystone api V3 only.

    .. versionadded:: 2016.11.0

    project_id
        The project id.

    name
        The project name.

    profile
        Configuration profile - if configuration for multiple openstack accounts required.

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.project_get c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.project_get project_id=c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.project_get name=nova
    '''
    kstone = auth(profile, **connection_args)

    if _client_version(kstone) > 2:
        return tenant_get(tenant_id=project_id, name=name, profile=None, **connection_args)
    else:
        return False


def tenant_list(profile=None, **connection_args):
    '''
    Return a list of available tenants (keystone tenants-list)

    CLI Example:

    .. code-block:: bash

        salt '*' keystone.tenant_list
    '''
    kstone = auth(profile, **connection_args)
    ret = {}

    for tenant in _project_mgr(kstone).list():
        ret[tenant.name] = dict((value, getattr(tenant, value)) for value in dir(tenant)
                                if not value.startswith('_') and
                                isinstance(getattr(tenant, value), (six.string_types, dict, bool)))
    return ret


def project_list(profile=None, **connection_args):
    '''
    Return a list of available projects (keystone projects-list).
    Overrides keystone tenants-list form api V2.
    For keystone api V3 only.

    .. versionadded:: 2016.11.0

    profile
        Configuration profile - if configuration for multiple openstack accounts required.

    CLI Example:

    .. code-block:: bash

        salt '*' keystone.project_list
    '''
    kstone = auth(profile, **connection_args)

    if _client_version(kstone) > 2:
        return tenant_list(profile, **connection_args)
    else:
        return False


def tenant_update(tenant_id=None, name=None, description=None,
                  enabled=None, profile=None, **connection_args):
    '''
    Update a tenant's information (keystone tenant-update)
    The following fields may be updated: name, description, enabled.
    Can only update name if targeting by ID

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.tenant_update name=admin enabled=True
        salt '*' keystone.tenant_update c965f79c4f864eaaa9c3b41904e67082 name=admin email=admin@domain.com
    '''
    kstone = auth(profile, **connection_args)

    if not tenant_id:
        for tenant in _project_mgr(kstone).list():
            if tenant.name == name:
                tenant_id = tenant.id
                break
    if not tenant_id:
        return {'Error': 'Unable to resolve tenant id'}

    tenant = _project_mgr(kstone).get(tenant_id)
    if not name:
        name = tenant.name
    if not description:
        description = tenant.description
    if enabled is None:
        enabled = tenant.enabled
    updated = _project_mgr(kstone).update(tenant_id, name=name, description=description, enabled=enabled)

    return dict((value, getattr(updated, value)) for value in dir(updated)
                if not value.startswith('_') and
                isinstance(getattr(updated, value), (six.string_types, dict, bool)))


def project_update(project_id=None, name=None, description=None,
                   enabled=None, profile=None, **connection_args):
    '''
    Update a tenant's information (keystone project-update)
    The following fields may be updated: name, description, enabled.
    Can only update name if targeting by ID

    Overrides keystone tenant_update form api V2.
    For keystone api V3 only.

    .. versionadded:: 2016.11.0

    project_id
        The project id.

    name
        The project name, which must be unique within the owning domain.

    description
        The project description.

    enabled
        Enables or disables the project.

    profile
        Configuration profile - if configuration for multiple openstack accounts required.

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.project_update name=admin enabled=True
        salt '*' keystone.project_update c965f79c4f864eaaa9c3b41904e67082 name=admin email=admin@domain.com
    '''
    kstone = auth(profile, **connection_args)

    if _client_version(kstone) > 2:
        return tenant_update(tenant_id=project_id, name=name, description=description,
                             enabled=enabled, profile=profile, **connection_args)
    else:
        return False


def token_get(profile=None, **connection_args):
    '''
    Return the configured tokens (keystone token-get)

    CLI Example:

    .. code-block:: bash

        salt '*' keystone.token_get c965f79c4f864eaaa9c3b41904e67082
    '''
    kstone = auth(profile, **connection_args)
    token = kstone.service_catalog.get_token()
    return {'id': token['id'],
            'expires': token['expires'],
            'user_id': token['user_id'],
            'tenant_id': token['tenant_id']}


def user_list(profile=None, **connection_args):
    '''
    Return a list of available users (keystone user-list)

    CLI Example:

    .. code-block:: bash

        salt '*' keystone.user_list
    '''
    kstone = auth(profile, **connection_args)
    ret = {}
    for user in kstone.users.list():
        ret[user.name] = dict((value, getattr(user, value, None)) for value in dir(user)
                              if not value.startswith('_') and
                              isinstance(getattr(user, value, None), (six.string_types, dict, bool)))
        tenant_id = getattr(user, 'tenantId', None)
        if tenant_id:
            ret[user.name]['tenant_id'] = tenant_id
    return ret


def user_get(user_id=None, name=None, profile=None, **connection_args):
    '''
    Return a specific users (keystone user-get)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.user_get c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.user_get user_id=c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.user_get name=nova
    '''
    kstone = auth(profile, **connection_args)
    ret = {}
    if name:
        for user in kstone.users.list():
            if user.name == name:
                user_id = user.id
                break
    if not user_id:
        return {'Error': 'Unable to resolve user id'}
    try:
        user = kstone.users.get(user_id)
    except keystoneclient.exceptions.NotFound:
        msg = 'Could not find user \'{0}\''.format(user_id)
        log.error(msg)
        return {'Error': msg}

    ret[user.name] = dict((value, getattr(user, value, None)) for value in dir(user)
                          if not value.startswith('_') and
                          isinstance(getattr(user, value, None), (six.string_types, dict, bool)))

    tenant_id = getattr(user, 'tenantId', None)
    if tenant_id:
        ret[user.name]['tenant_id'] = tenant_id
    return ret


def user_create(name, password, email, tenant_id=None,
                enabled=True, profile=None, project_id=None, description=None, **connection_args):
    '''
    Create a user (keystone user-create)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.user_create name=jack password=zero email=jack@halloweentown.org \
        tenant_id=a28a7b5a999a455f84b1f5210264375e enabled=True
    '''
    kstone = auth(profile, **connection_args)

    if _client_version(kstone) > 2:
        if tenant_id and not project_id:
            project_id = tenant_id
        item = kstone.users.create(name=name,
                                   password=password,
                                   email=email,
                                   project_id=project_id,
                                   enabled=enabled,
                                   description=description)
    else:
        item = kstone.users.create(name=name,
                                   password=password,
                                   email=email,
                                   tenant_id=tenant_id,
                                   enabled=enabled)
    return user_get(item.id, profile=profile, **connection_args)


def user_delete(user_id=None, name=None, profile=None, **connection_args):
    '''
    Delete a user (keystone user-delete)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.user_delete c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.user_delete user_id=c965f79c4f864eaaa9c3b41904e67082
        salt '*' keystone.user_delete name=nova
    '''
    kstone = auth(profile, **connection_args)
    if name:
        for user in kstone.users.list():
            if user.name == name:
                user_id = user.id
                break
    if not user_id:
        return {'Error': 'Unable to resolve user id'}
    kstone.users.delete(user_id)
    ret = 'User ID {0} deleted'.format(user_id)
    if name:

        ret += ' ({0})'.format(name)
    return ret


def user_update(user_id=None, name=None, email=None, enabled=None, options=None,
                tenant=None, profile=None, project=None, description=None, **connection_args):
    '''
    Update a user's information (keystone user-update)
    The following fields may be updated: name, email, enabled, tenant, options.
    Because the name is one of the fields, a valid user id is required.

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.user_update user_id=c965f79c4f864eaaa9c3b41904e67082 name=newname
        salt '*' keystone.user_update c965f79c4f864eaaa9c3b41904e67082 name=newname email=newemail@domain.com
    '''
    kstone = auth(profile, **connection_args)
    if not user_id:
        for user in kstone.users.list():
            if user.name == name:
                user_id = user.id
                break
        if not user_id:
            return {'Error': 'Unable to resolve user id'}
    user = kstone.users.get(user_id)
    # Keep previous settings if not updating them
    if not name:
        name = user.name
    if not email:
        email = user.email
    if enabled is None:
        enabled = user.enabled
    if not options:
       options = {}

    if _client_version(kstone) > 2:
        if description is None:
            description = getattr(user, 'description', None)
        else:
            description = str(description)

        project_id = None
        if project:
            for proj in kstone.projects.list():
                if proj.name == project:
                    project_id = proj.id
                    break
        if not project_id:
            project_id = getattr(user, 'project_id', None)

        kstone.users.update(user=user_id, name=name, email=email, enabled=enabled, description=description,
                            options=options, project_id=project_id)
    else:
        kstone.users.update(user=user_id, name=name, email=email, options=options, enabled=enabled)

        tenant_id = None
        if tenant:
            for tnt in kstone.tenants.list():
                if tnt.name == tenant:
                    tenant_id = tnt.id
                    break
            if tenant_id:
                kstone.users.update_tenant(user_id, tenant_id)

    ret = 'Info updated for user ID {0}'.format(user_id)
    return ret


def user_verify_password(user_id=None, name=None, password=None,
                         profile=None, **connection_args):
    '''
    Verify a user's password

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.user_verify_password name=test password=foobar
        salt '*' keystone.user_verify_password user_id=c965f79c4f864eaaa9c3b41904e67082 password=foobar
    '''
    kstone = auth(profile, **connection_args)
    if 'connection_endpoint' in connection_args:
        auth_url = connection_args.get('connection_endpoint')
    else:
        if _client_version(kstone) > 2:
            auth_url = __salt__['config.option']('keystone.endpoint',
                                                 'http://127.0.0.1:35357/v3')
        else:
            auth_url = __salt__['config.option']('keystone.endpoint',
                                                 'http://127.0.0.1:35357/v2.0')

    if user_id:
        for user in kstone.users.list():
            if user.id == user_id:
                name = user.name
                break
    if not name:
        return {'Error': 'Unable to resolve user name'}
    kwargs = {'username': name,
              'password': password,
              'auth_url': auth_url}
    try:
        if _client_version(kstone) > 2:
            client3.Client(**kwargs).authenticate()
        else:
            client.Client(**kwargs).authenticate()
    except (keystoneclient.exceptions.Unauthorized,
            keystoneclient.exceptions.AuthorizationFailure):
        return False
    return True


def user_password_update(user_id=None, name=None, password=None,
                         profile=None, **connection_args):
    '''
    Update a user's password (keystone user-password-update)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.user_password_update c965f79c4f864eaaa9c3b41904e67082 password=12345
        salt '*' keystone.user_password_update user_id=c965f79c4f864eaaa9c3b41904e67082 password=12345
        salt '*' keystone.user_password_update name=nova password=12345
    '''
    kstone = auth(profile, **connection_args)
    if name:
        for user in kstone.users.list():
            if user.name == name:
                user_id = user.id
                break
    if not user_id:
        return {'Error': 'Unable to resolve user id'}

    if _client_version(kstone) > 2:
        kstone.users.update(user=user_id, password=password)
    else:
        kstone.users.update_password(user=user_id, password=password)
    ret = 'Password updated for user ID {0}'.format(user_id)
    if name:
        ret += ' ({0})'.format(name)
    return ret


def user_role_add(user_id=None, user=None, tenant_id=None,
                  tenant=None, role_id=None, role=None, profile=None,
                  project_id=None, project_name=None, **connection_args):
    '''
    Add role for user in tenant (keystone user-role-add)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.user_role_add \
user_id=298ce377245c4ec9b70e1c639c89e654 \
tenant_id=7167a092ece84bae8cead4bf9d15bb3b \
role_id=ce377245c4ec9b70e1c639c89e8cead4
        salt '*' keystone.user_role_add user=admin tenant=admin role=admin
    '''
    kstone = auth(profile, **connection_args)

    if project_id and not tenant_id:
        tenant_id = project_id
    elif project_name and not tenant:
        tenant = project_name

    if user:
        user_id = user_get(name=user, profile=profile,
                           **connection_args)[user].get('id')
    else:
        user = next(six.iterkeys(user_get(user_id, profile=profile,
                                          **connection_args)))['name']
    if not user_id:
        return {'Error': 'Unable to resolve user id'}

    if tenant:
        tenant_id = tenant_get(name=tenant, profile=profile,
                               **connection_args)[tenant].get('id')
    else:
        tenant = next(six.iterkeys(tenant_get(tenant_id, profile=profile,
                                              **connection_args)))['name']
    if not tenant_id:
        return {'Error': 'Unable to resolve tenant/project id'}

    if role:
        role_id = role_get(name=role, profile=profile,
                           **connection_args)[role]['id']
    else:
        role = next(six.iterkeys(role_get(role_id, profile=profile,
                                          **connection_args)))['name']
    if not role_id:
        return {'Error': 'Unable to resolve role id'}

    if _client_version(kstone) > 2:
        kstone.roles.grant(role_id, user=user_id, project=tenant_id)
    else:
        kstone.roles.add_user_role(user_id, role_id, tenant_id)
    ret_msg = '"{0}" role added for user "{1}" for "{2}" tenant/project'
    return ret_msg.format(role, user, tenant)


def user_role_remove(user_id=None, user=None, tenant_id=None,
                     tenant=None, role_id=None, role=None,
                     profile=None, project_id=None, project_name=None, **connection_args):
    '''
    Remove role for user in tenant (keystone user-role-remove)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.user_role_remove \
user_id=298ce377245c4ec9b70e1c639c89e654 \
tenant_id=7167a092ece84bae8cead4bf9d15bb3b \
role_id=ce377245c4ec9b70e1c639c89e8cead4
        salt '*' keystone.user_role_remove user=admin tenant=admin role=admin
    '''
    kstone = auth(profile, **connection_args)

    if project_id and not tenant_id:
        tenant_id = project_id
    elif project_name and not tenant:
        tenant = project_name

    if user:
        user_id = user_get(name=user, profile=profile,
                           **connection_args)[user].get('id')
    else:
        user = next(six.iterkeys(user_get(user_id, profile=profile,
                                          **connection_args)))['name']
    if not user_id:
        return {'Error': 'Unable to resolve user id'}

    if tenant:
        tenant_id = tenant_get(name=tenant, profile=profile,
                               **connection_args)[tenant].get('id')
    else:
        tenant = next(six.iterkeys(tenant_get(tenant_id, profile=profile,
                                              **connection_args)))['name']
    if not tenant_id:
        return {'Error': 'Unable to resolve tenant/project id'}

    if role:
        role_id = role_get(name=role, profile=profile,
                           **connection_args)[role]['id']
    else:
        role = next(six.iterkeys(role_get(role_id)))['name']
    if not role_id:
        return {'Error': 'Unable to resolve role id'}

    if _client_version(kstone) > 2:
        kstone.roles.revoke(role_id, user=user_id, project=tenant_id)
    else:
        kstone.roles.remove_user_role(user_id, role_id, tenant_id)
    ret_msg = '"{0}" role removed for user "{1}" under "{2}" tenant'
    return ret_msg.format(role, user, tenant)


def user_role_list(user_id=None, tenant_id=None, user_name=None,
                   tenant_name=None, profile=None, project_id=None, project_name=None, **connection_args):
    '''
    Return a list of available user_roles (keystone user-roles-list)

    CLI Examples:

    .. code-block:: bash

        salt '*' keystone.user_role_list \
user_id=298ce377245c4ec9b70e1c639c89e654 \
tenant_id=7167a092ece84bae8cead4bf9d15bb3b
        salt '*' keystone.user_role_list user_name=admin tenant_name=admin
    '''
    kstone = auth(profile, **connection_args)
    ret = {}

    if project_id and not tenant_id:
        tenant_id = project_id
    elif project_name and not tenant_name:
        tenant_name = project_name

    if user_name:
        for user in kstone.users.list():
            if user.name == user_name:
                user_id = user.id
                break
    if tenant_name:
        for tenant in _project_mgr(kstone).list():
            if tenant.name == tenant_name:
                tenant_id = tenant.id
                break
    if not user_id or not tenant_id:
        return {'Error': 'Unable to resolve user or tenant/project id'}

    if _client_version(kstone) > 2:
        for role in kstone.roles.list(user=user_id, project=tenant_id):
            ret[role.name] = dict((value, getattr(role, value)) for value in dir(role)
                                  if not value.startswith('_') and
                                  isinstance(getattr(role, value), (six.string_types, dict, bool)))
    else:
        for role in kstone.roles.roles_for_user(user=user_id, tenant=tenant_id):
            ret[role.name] = {'id': role.id,
                              'name': role.name,
                              'user_id': user_id,
                              'tenant_id': tenant_id}
    return ret


def _item_list(profile=None, **connection_args):
    '''
    Template for writing list functions
    Return a list of available items (keystone items-list)

    CLI Example:

    .. code-block:: bash

        salt '*' keystone.item_list
    '''
    kstone = auth(profile, **connection_args)
    ret = []
    for item in kstone.items.list():
        ret.append(item.__dict__)
        # ret[item.name] = {
        #         'id': item.id,
        #         'name': item.name,
        #         }
    return ret

    # The following is a list of functions that need to be incorporated in the
    # keystone module. This list should be updated as functions are added.
    #
    # endpoint-create     Create a new endpoint associated with a service
    # endpoint-delete     Delete a service endpoint
    # discover            Discover Keystone servers and show authentication
    #                     protocols and
    # bootstrap           Grants a new role to a new user on a new tenant, after
    #                     creating each.
