# -*- coding: utf-8 -*-
"""
Module extending the salt.modules.glance modules.

This module adds functionality for managing Glance V2 tasks by exposing the
following functions:
  - task_create
  - task_show
  - task_list

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

        keystone.user: admin
        keystone.password: verybadpass
        keystone.tenant: admin
        keystone.insecure: False   #(optional)
        keystone.auth_url: 'http://127.0.0.1:5000/v2.0/'

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

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

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

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

        salt '*' glance.image_list profile=openstack1
"""

# Import Python libs
from __future__ import absolute_import
import logging
import pprint
import re

# Import salt libs
from salt.exceptions import SaltInvocationError

from salt.version import (
    __version__,
    SaltStackVersion
    )

from salt.utils import warn_until

# pylint: disable=import-error
HAS_GLANCE = False
try:
    from glanceclient import client
    from glanceclient import exc
    HAS_GLANCE = True
except ImportError:
    pass


logging.basicConfig(level=logging.DEBUG)
log = logging.getLogger(__name__)


def __virtual__():
    '''
    Only load this module if glance
    is installed on this minion.
    '''
    if not HAS_GLANCE:
        return False, ("The glance execution module cannot be loaded: "
                       "the glanceclient python library is not available.")
    return True


__opts__ = {}


def _auth(profile=None, api_version=2, **connection_args):
    '''
    Set up glance credentials, returns
    `glanceclient.client.Client`. Optional parameter
    "api_version" defaults to 2.

    Only intended to be used within glance-enabled modules
    '''

    kstone = __salt__['keystoneng.auth'](profile, **connection_args)
    g_endpoint = __salt__['keystoneng.endpoint_get']('glance', profile=profile)
    glance_client = client.Client(api_version, session=kstone.session, endpoint=g_endpoint.get('url'))
    return glance_client


def _validate_image_params(visibility=None, container_format='bare',
                           disk_format='raw', tags=None, **kwargs):
    # valid options for "visibility":
    v_list = ['public', 'private', 'shared', 'community']
    # valid options for "container_format":
    cf_list = ['ami', 'ari', 'aki', 'bare', 'ovf']
    # valid options for "disk_format":
    df_list = ['ami', 'ari', 'aki', 'vhd', 'vmdk',
               'raw', 'qcow2', 'vdi', 'iso']

    if visibility is not None:
        if visibility not in v_list:
            raise SaltInvocationError('"visibility" needs to be one ' +
                                      'of the following: {0}'.format(
                                          ', '.join(v_list)))
    if container_format not in cf_list:
        raise SaltInvocationError('"container_format" needs to be ' +
                                  'one of the following: {0}'.format(
                                      ', '.join(cf_list)))
    if disk_format not in df_list:
        raise SaltInvocationError('"disk_format" needs to be one ' +
                                  'of the following: {0}'.format(
                                      ', '.join(df_list)))
    if tags:
        if not isinstance(tags, list):
            raise SaltInvocationError('Incorrect input type for the {0} '
                                      'parameter: expected: {1}, '
                                      'got {2}'.format("tags", list,
                                                       type(tags)))


def _validate_task_params(task_type, input_params):
    # Only import tasks are currently supported
    # TODO(eezhova): Add support for "export" and "clone" task types
    valid_task_types = ["import", ]

    import_required_params = {"import_from", "import_from_format",
                              "image_properties"}

    if task_type not in valid_task_types:
        raise SaltInvocationError("'task_type' must be one of the following: "
                                  "{0}".format(', '.join(valid_task_types)))

    if task_type == "import":
        valid_import_from_formats = ['ami', 'ari', 'aki', 'vhd', 'vmdk',
                                     'raw', 'qcow2', 'vdi', 'iso']
        missing_params = import_required_params - set(input_params.keys())
        if missing_params:
            raise SaltInvocationError(
                "Missing the following task parameters for the 'import' task: "
                "{0}".format(', '.join(missing_params)))

        import_from = input_params['import_from']
        import_from_format = input_params['import_from_format']
        image_properties = input_params['image_properties']
        if not import_from.startswith(('http://', 'https://')):
            raise SaltInvocationError("Only non-local sources of image data "
                                      "are supported.")
        if import_from_format not in valid_import_from_formats:
            raise SaltInvocationError(
                "'import_from_format' needs to be one of the following: "
                "{0}".format(', '.join(valid_import_from_formats)))
        _validate_image_params(**image_properties)


def task_create(task_type, profile=None, input_params=None):
    """
    Create a Glance V2 task of a given type

    :param task_type: Task type
    :param profile: Authentication profile
    :param input_params: Dictionary with input parameters for a task
    :return: Dictionary with created task's parameters
    """
    g_client = _auth(profile, api_version=2)
    log.debug(
        'Task type: {}\nInput params: {}'.format(task_type, input_params)
    )
    task = g_client.tasks.create(type=task_type, input=input_params)
    log.debug("Created task: {}".format(dict(task)))
    created_task = task_show(task.id, profile=profile)
    return created_task


def task_show(task_id, profile=None):
    """
    Show a Glance V2 task

    :param task_id: ID of a task to show
    :param profile: Authentication profile
    :return: Dictionary with created task's parameters
    """
    g_client = _auth(profile)
    ret = {}
    try:
        task = g_client.tasks.get(task_id)
    except exc.HTTPNotFound:
        return {
            'result': False,
            'comment': 'No task with ID {0}'.format(task_id)
        }
    pformat = pprint.PrettyPrinter(indent=4).pformat
    log.debug('Properties of task {0}:\n{1}'.format(
        task_id, pformat(task)))

    schema = image_schema(schema_type='task', profile=profile)
    if len(schema.keys()) == 1:
        schema = schema['task']
    for key in schema.keys():
        if key in task:
            ret[key] = task[key]
    return ret


def task_list(profile=None):
    """
    List Glance V2 tasks

    :param profile: Authentication profile
    :return: Dictionary with existing tasks
    """
    g_client = _auth(profile)
    ret = {}
    tasks = g_client.tasks.list()
    schema = image_schema(schema_type='task', profile=profile)
    if len(schema.keys()) == 1:
        schema = schema['task']
    for task in tasks:
        task_dict = {}
        for key in schema.keys():
            if key in task:
                task_dict[key] = task[key]
        ret[task['id']] = task_dict
    return ret


def get_image_owner_id(name, profile=None):
    """
    Mine function to get image owner

    :param name: Name of the image
    :param profile: Authentication profile
    :return: Image owner ID or [] if image is not found
    """
    g_client = _auth(profile)
    image_id = None
    for image in g_client.images.list():
        if image.name == name:
            image_id = image.id
            continue
    if not image_id:
        return []
    try:
        image = g_client.images.get(image_id)
    except exc.HTTPNotFound:
        return []
    return image['owner']


def image_schema(schema_type='image', profile=None):
    '''
    Returns names and descriptions of the schema "image"'s
    properties for this profile's instance of glance

    CLI Example:

    .. code-block:: bash

        salt '*' glance.image_schema
    '''
    return schema_get(schema_type, profile)


def schema_get(name, profile=None):
    '''
    Known valid names of schemas are:
      - image
      - images
      - member
      - members

    CLI Example:

    .. code-block:: bash

        salt '*' glance.schema_get name=f16-jeos
    '''
    g_client = _auth(profile)
    pformat = pprint.PrettyPrinter(indent=4).pformat
    schema_props = {}
    for prop in g_client.schemas.get(name).properties:
        schema_props[prop.name] = prop.description
    log.debug('Properties of schema {0}:\n{1}'.format(
        name, pformat(schema_props)))
    return {name: schema_props}

def image_list(id=None, profile=None, name=None):  # pylint: disable=C0103
    '''
    Return a list of available images (glance image-list)

    CLI Example:

    .. code-block:: bash

        salt '*' glance.image_list
    '''

    g_client = _auth(profile)
    ret = []
    for image in g_client.images.list():
        if id is None and name is None:
            _add_image(ret, image)
        else:
            if id is not None and id == image.id:
                _add_image(ret, image)
                return ret
            if name == image.name:
                if name in ret:
                    # Not really worth an exception
                    return {
                        'result': False,
                        'comment':
                            'More than one image with '
                            'name "{0}"'.format(name)
                        }
                _add_image(ret, image)
    log.debug('Returning images: {0}'.format(ret))
    return ret

def _add_image(collection, image):
    '''
    Add image to given dictionary
    '''
    image_prep = {
            'id': image.id,
            'name': image.name,
            'created_at': image.created_at,
            'file': image.file,
            'min_disk': image.min_disk,
            'min_ram': image.min_ram,
            'owner': image.owner,
            'protected': image.protected,
            'status': image.status,
            'tags': image.tags,
            'updated_at': image.updated_at,
            'visibility': image.visibility,
        }
    # Those cause AttributeErrors in Icehouse' glanceclient
    for attr in ['container_format', 'disk_format', 'size']:
        if attr in image:
            image_prep[attr] = image[attr]
    if type(collection) is dict:
        collection[image.name] = image_prep
    elif type(collection) is list:
        collection.append(image_prep)
    else:
        msg = '"collection" is {0}'.format(type(collection)) +\
            'instead of dict or list.'
        log.error(msg)
        raise TypeError(msg)
    return collection

def image_create(name, location=None, profile=None, visibility=None,
        container_format='bare', disk_format='raw', protected=None,
        copy_from=None, is_public=None):
    '''
    Create an image (glance image-create)

    CLI Example, old format:

    .. code-block:: bash

        salt '*' glance.image_create name=f16-jeos is_public=true \\
                 disk_format=qcow2 container_format=ovf \\
                 copy_from=http://berrange.fedorapeople.org/\
                    images/2012-02-29/f16-x86_64-openstack-sda.qcow2

    CLI Example, new format resembling Glance API v2:

    .. code-block:: bash

        salt '*' glance.image_create name=f16-jeos visibility=public \\
                 disk_format=qcow2 container_format=ovf \\
                 copy_from=http://berrange.fedorapeople.org/\
                    images/2012-02-29/f16-x86_64-openstack-sda.qcow2

    The parameter 'visibility' defaults to 'public' if neither
    'visibility' nor 'is_public' is specified.
    '''
    kwargs = {}
    # valid options for "visibility":
    v_list = ['public', 'private']
    # valid options for "container_format":
    cf_list = ['ami', 'ari', 'aki', 'bare', 'ovf']
    # valid options for "disk_format":
    df_list = ['ami', 'ari', 'aki', 'vhd', 'vmdk',
               'raw', 'qcow2', 'vdi', 'iso']
    # 'location' and 'visibility' are the parameters used in
    # Glance API v2. For now we have to use v1 for now (see below)
    # but this modules interface will change in Carbon.
    if copy_from is not None or is_public is not None:
        warn_until('Carbon', 'The parameters \'copy_from\' and '
            '\'is_public\' are deprecated and will be removed. '
            'Use \'location\' and \'visibility\' instead.')
    if is_public is not None and visibility is not None:
        raise SaltInvocationError('Must only specify one of '
            '\'is_public\' and \'visibility\'')
    if copy_from is not None and location is not None:
        raise SaltInvocationError('Must only specify one of '
            '\'copy_from\' and \'location\'')
    if copy_from is not None:
        kwargs['copy_from'] = copy_from
    else:
        kwargs['copy_from'] = location
    if is_public is not None:
        kwargs['is_public'] = is_public
    elif visibility is not None:
        if visibility not in v_list:
            raise SaltInvocationError('"visibility" needs to be one ' +
                'of the following: {0}'.format(', '.join(v_list)))
        elif visibility == 'public':
            kwargs['is_public'] = True
        else:
            kwargs['is_public'] = False
    else:
        kwargs['is_public'] = True
    if container_format not in cf_list:
        raise SaltInvocationError('"container_format" needs to be ' +
            'one of the following: {0}'.format(', '.join(cf_list)))
    else:
        kwargs['container_format'] = container_format
    if disk_format not in df_list:
        raise SaltInvocationError('"disk_format" needs to be one ' +
            'of the following: {0}'.format(', '.join(df_list)))
    else:
        kwargs['disk_format'] = disk_format
    if protected is not None:
        kwargs['protected'] = protected
    # Icehouse's glanceclient doesn't have add_location() and
    # glanceclient.v2 doesn't implement Client.images.create()
    # in a usable fashion. Thus we have to use v1 for now.
    g_client = _auth(profile, api_version=1)
    image = g_client.images.create(name=name, **kwargs)
    return image_show(image.id, profile=profile)

def image_delete(id=None, name=None, profile=None):  # pylint: disable=C0103
    '''
    Delete an image (glance image-delete)

    CLI Examples:

    .. code-block:: bash

        salt '*' glance.image_delete c2eb2eb0-53e1-4a80-b990-8ec887eae7df
        salt '*' glance.image_delete id=c2eb2eb0-53e1-4a80-b990-8ec887eae7df
        salt '*' glance.image_delete name=f16-jeos
    '''
    g_client = _auth(profile)
    image = {'id': False, 'name': None}
    if name:
        for image in g_client.images.list():
            if image.name == name:
                id = image.id  # pylint: disable=C0103
                continue
    if not id:
        return {
            'result': False,
            'comment':
                'Unable to resolve image id '
                'for name {0}'.format(name)
            }
    elif not name:
        name = image['name']
    try:
        g_client.images.delete(id)
    except exc.HTTPNotFound:
        return {
            'result': False,
            'comment': 'No image with ID {0}'.format(id)
            }
    except exc.HTTPForbidden as forbidden:
        log.error(str(forbidden))
        return {
            'result': False,
            'comment': str(forbidden)
            }
    return {
        'result': True,
        'comment': 'Deleted image \'{0}\' ({1}).'.format(name, id),
        }

def image_show(id=None, name=None, profile=None):  # pylint: disable=C0103
    '''
    Return details about a specific image (glance image-show)

    CLI Example:

    .. code-block:: bash

        salt '*' glance.image_show
    '''
    g_client = _auth(profile)
    ret = {}
    if name:
        for image in g_client.images.list():
            if image.name == name:
                id = image.id  # pylint: disable=C0103
                continue
    if not id:
        return {
            'result': False,
            'comment':
                'Unable to resolve image ID '
                'for name \'{0}\''.format(name)
            }
    try:
        image = g_client.images.get(id)
    except exc.HTTPNotFound:
        return {
            'result': False,
            'comment': 'No image with ID {0}'.format(id)
            }
    pformat = pprint.PrettyPrinter(indent=4).pformat
    log.debug('Properties of image {0}:\n{1}'.format(
        image.name, pformat(image)))
    schema = image_schema(profile=profile)
    if len(schema.keys()) == 1:
        schema = schema['image']
    for key in schema.keys():
        if key in image:
            ret[key] = image[key]
    return ret

def image_update(id=None, name=None, profile=None, **kwargs):  # pylint: disable=C0103
    '''
    Update properties of given image.
    Known to work for:
    - min_ram (in MB)
    - protected (bool)
    - visibility ('public' or 'private')

    CLI Example:

    .. code-block:: bash

        salt '*' glance.image_update id=c2eb2eb0-53e1-4a80-b990-8ec887eae7df
        salt '*' glance.image_update name=f16-jeos
    '''
    if id:
        image = image_show(id=id, profile=profile)
        if 'result' in image and not image['result']:
            return image
        elif len(image) == 1:
            image = image.values()[0]
    elif name:
        img_list = image_list(name=name, profile=profile)
        if img_list is dict and 'result' in img_list:
            return img_list
        elif len(img_list) == 0:
            return {
                'result': False,
                'comment':
                    'No image with name \'{0}\' '
                    'found.'.format(name)
                }
        elif len(img_list) == 1:
            try:
                image = img_list[0]
            except KeyError:
                image = img_list[name]
    else:
        raise SaltInvocationError
    log.debug('Found image:\n{0}'.format(image))
    to_update = {}
    for key, value in kwargs.items():
        if key.startswith('_'):
            continue
        if key not in image or image[key] != value:
            log.debug('add <{0}={1}> to to_update'.format(key, value))
            to_update[key] = value
    g_client = _auth(profile)
    updated = g_client.images.update(image['id'], **to_update)
    return updated

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

    CLI Example:

    .. code-block:: bash

        salt '*' glance.item_list
    '''
    g_client = _auth(profile)
    ret = []
    for item in g_client.items.list():
        ret.append(item.__dict__)
        #ret[item.name] = {
        #        'name': item.name,
        #    }
    return ret
