# -*- coding: utf-8 -*-
'''
Module for sending messages to Pushover (https://www.pushover.net)

.. versionadded:: 2016.3.0

:configuration: This module can be used by either passing an api key and version
    directly or by specifying both in a configuration profile in the salt
    master/minion config.

    For example:

    .. code-block:: yaml

        pushover:
          token: abAHuZyCLtdH8P4zhmFZmgUHUsv1ei8
'''

# Import Python libs
from __future__ import absolute_import, print_function, unicode_literals
import logging

# Import 3rd-party libs
# pylint: disable=import-error,no-name-in-module,redefined-builtin
from salt.ext.six.moves.urllib.parse import urlencode as _urlencode
# pylint: enable=import-error,no-name-in-module,redefined-builtin

# Import salt libs
from salt.exceptions import SaltInvocationError
import salt.utils.pushover

log = logging.getLogger(__name__)
__virtualname__ = 'pushover'


def __virtual__():
    '''
    Return virtual name of the module.

    :return: The virtual name of the module.
    '''
    return __virtualname__


def post_message(user=None,
                 device=None,
                 message=None,
                 title=None,
                 priority=None,
                 expire=None,
                 retry=None,
                 sound=None,
                 api_version=1,
                 token=None):
    '''
    Send a message to a Pushover user or group.

    :param user:        The user or group to send to, must be key of user or group not email address.
    :param message:     The message to send to the PushOver user or group.
    :param title:       Specify who the message is from.
    :param priority:    The priority of the message, defaults to 0.
    :param expire:      The message should expire after N number of seconds.
    :param retry:       The number of times the message should be retried.
    :param sound:       The sound to associate with the message.
    :param api_version: The PushOver API version, if not specified in the configuration.
    :param token:       The PushOver token, if not specified in the configuration.
    :return:            Boolean if message was sent successfully.

    CLI Example:

    .. code-block:: bash

        salt '*' pushover.post_message user='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' title='Message from Salt' message='Build is done'

        salt '*' pushover.post_message user='xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' title='Message from Salt' message='Build is done' priority='2' expire='720' retry='5'

    '''

    if not token:
        token = __salt__['config.get']('pushover.token') or \
                __salt__['config.get']('pushover:token')
        if not token:
            raise SaltInvocationError('Pushover token is unavailable.')

    if not user:
        user = __salt__['config.get']('pushover.user') or \
               __salt__['config.get']('pushover:user')
        if not user:
            raise SaltInvocationError('Pushover user key is unavailable.')

    if not message:
        raise SaltInvocationError('Required parameter "message" is missing.')

    user_validate = salt.utils.pushover.validate_user(user, device, token)
    if not user_validate['result']:
        return user_validate

    if not title:
        title = 'Message from SaltStack'

    parameters = dict()
    parameters['user'] = user
    parameters['device'] = device
    parameters['token'] = token
    parameters['title'] = title
    parameters['priority'] = priority
    parameters['expire'] = expire
    parameters['retry'] = retry
    parameters['message'] = message

    if sound and salt.utils.pushover.validate_sound(sound, token)['res']:
        parameters['sound'] = sound

    result = salt.utils.pushover.query(function='message',
                                       method='POST',
                                       header_dict={'Content-Type': 'application/x-www-form-urlencoded'},
                                       data=_urlencode(parameters),
                                       opts=__opts__)

    if result['res']:
        return True
    else:
        return result
