# -*- coding: utf-8 -*-
'''
Manage virt
===========

For the key certificate this state uses the external pillar in the master to call
for the generation and signing of certificates for systems running libvirt:

.. code-block:: yaml

    libvirt_keys:
      virt.keys
'''
from __future__ import absolute_import

# Import python libs
import os
try:
    import libvirt  # pylint: disable=import-error
    HAS_LIBVIRT = True
except ImportError:
    HAS_LIBVIRT = False

# Import salt libs
import salt.utils


def __virtual__():
    '''
    Only if libvirt bindings for Python are installed.

    :return:
    '''

    return HAS_LIBVIRT


def keys(name, basepath='/etc/pki'):
    '''
    Manage libvirt keys.

    name
        The name variable used to track the execution

    basepath
        Defaults to ``/etc/pki``, this is the root location used for libvirt
        keys on the hypervisor
    '''
    #libvirt.serverkey.pem
    #libvirt.servercert.pem
    #libvirt.clientkey.pem
    #libvirt.clientcert.pem
    #libvirt.cacert.pem

    ret = {'name': name, 'changes': {}, 'result': True, 'comment': ''}
    pillar = __salt__['pillar.ext']({'libvirt': '_'})
    paths = {
        'serverkey': os.path.join(basepath, 'libvirt', 'private', 'serverkey.pem'),
        'servercert': os.path.join(basepath, 'libvirt', 'servercert.pem'),
        'clientkey': os.path.join(basepath, 'libvirt', 'private', 'clientkey.pem'),
        'clientcert': os.path.join(basepath,'libvirt','clientcert.pem'),
        'cacert': os.path.join(basepath, 'CA', 'cacert.pem')
    }

    for key in paths:
        p_key = 'libvirt.{0}.pem'.format(key)
        if p_key not in pillar:
            continue
        if not os.path.exists(os.path.dirname(paths[key])):
            os.makedirs(os.path.dirname(paths[key]))
        if os.path.isfile(paths[key]):
            with salt.utils.fopen(paths[key], 'r') as fp_:
                if fp_.read() != pillar[p_key]:
                    ret['changes'][key] = 'update'
        else:
            ret['changes'][key] = 'new'

    if not ret['changes']:
        ret['comment'] = 'All keys are correct'
    elif __opts__['test']:
        ret['result'] = None
        ret['comment'] = 'Libvirt keys are set to be updated'
        ret['changes'] = {}
    else:
        for key in ret['changes']:
            with salt.utils.fopen(paths[key], 'w+') as fp_:
                fp_.write(pillar['libvirt.{0}.pem'.format(key)])

        ret['comment'] = 'Updated libvirt certs and keys'

    return ret


def stopped(name):
    '''
    Stops a VM

    .. versionadded:: Boron

    .. code-block:: yaml

        domain_name:
          virt.stopped
    '''
    ret = {'name': name, 'changes': {}, 'result': True, 'comment': ''}

    try:
        ret['result'] = __salt__['virt.stop'](name)
    except libvirt.libvirtError as err:
        ret['result'] = False
        ret['comment'] = str(err)

    if ret['result']:
        ret['changes'] = {'stopped': name}
        ret['comment'] = "Machine has been abruptly turned off"

    return ret


@@ -3023,24 +3023,549 @@
 d off%22%0A%0A    return ret%0A%0A
+%0Adef running(name):%0A    '''%0A    Starts a VM%0A%0A    .. versionadded:: Boron%0A%0A    .. code-block:: yaml%0A%0A        domain_name:%0A          virt.running%0A    '''%0A    ret = %7B'name': name, 'changes': %7B%7D, 'result': True, 'comment': ''%7D%0A%0A    try:%0A        ret%5B'result'%5D = __salt__%5B'virt.start'%5D(name)%0A    except libvirt.libvirtError as err:%0A        ret%5B'result'%5D = False%0A        ret%5B'comment'%5D = str(err)%0A%0A    if ret%5B'result'%5D:%0A        ret%5B'changes'%5D = %7B'stopped': name%7D%0A        ret%5B'comment'%5D = %22Machine has been started%22%0A%0A    return ret%0A%0A

Implement "running" state