# -*- 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,
                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.
    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 _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,
                            project_id=project_id)
    else:
        kstone.users.update(user=user_id, name=name, email=email, 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)
        else:
            client.Client(**kwargs)
    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.
