# -*- coding: utf-8 -*-

# This file is copy of original /usr/lib/python2.7/dist-packages/salt/modules/rabbitmq.py
# with fix applied for PROD-35125 - rabbitmq module incompatible with rabbitmq-server 3.8+
# It fix native check_password function by override it here and call it from
# _states/rabbitmq_user_common.py which also introduced in this patch.
# Fix source: https://github.com/saltstack/salt/commit/d0e0ed6b60f4de6d2b2551cad2fc7a553efe0274

from __future__ import absolute_import

# Import python libs
import json
import re
import logging
import os
import os.path
import random
import string

# Import salt libs
import salt.utils
import salt.utils.itertools
import salt.ext.six as six
from salt.exceptions import SaltInvocationError
from salt.ext.six.moves import range
from salt.exceptions import CommandExecutionError

log = logging.getLogger(__name__)

RABBITMQCTL = None
RABBITMQ_PLUGINS = None


def __virtual__():
    '''
    Verify RabbitMQ is installed.
    '''
    global RABBITMQCTL
    global RABBITMQ_PLUGINS

    if salt.utils.is_windows():
        from salt.ext.six.moves import winreg
        key = None
        try:
            key = winreg.OpenKeyEx(
                winreg.HKEY_LOCAL_MACHINE,
                'SOFTWARE\\VMware, Inc.\\RabbitMQ Server',
                0,
                winreg.KEY_READ | winreg.KEY_WOW64_32KEY
            )
            (dir_path, value_type) = winreg.QueryValueEx(
                key,
                'Install_Dir'
            )
            if value_type != winreg.REG_SZ:
                raise TypeError('Invalid RabbitMQ Server directory type: {0}'.format(value_type))
            if not os.path.isdir(dir_path):
                raise IOError('RabbitMQ directory not found: {0}'.format(dir_path))
            subdir_match = ''
            for name in os.listdir(dir_path):
                if name.startswith('rabbitmq_server-'):
                    subdir_path = os.path.join(dir_path, name)
                    # Get the matching entry that is last in ASCII order.
                    if os.path.isdir(subdir_path) and subdir_path > subdir_match:
                        subdir_match = subdir_path
            if not subdir_match:
                raise IOError('"rabbitmq_server-*" subdirectory not found in: {0}'.format(dir_path))
            RABBITMQCTL = os.path.join(subdir_match, 'sbin', 'rabbitmqctl.bat')
            RABBITMQ_PLUGINS = os.path.join(subdir_match, 'sbin', 'rabbitmq-plugins.bat')
        except Exception:
            pass
        finally:
            if key is not None:
                winreg.CloseKey(key)
    else:
        RABBITMQCTL = salt.utils.which('rabbitmqctl')
        RABBITMQ_PLUGINS = salt.utils.which('rabbitmq-plugins')

    if not RABBITMQCTL:
        return (False, 'Module rabbitmq: module only works when RabbitMQ is installed')
    return True


def _format_response(response, msg):
    if isinstance(response, dict):
        if response['retcode'] != 0 or response['stderr']:
            raise CommandExecutionError(
                'RabbitMQ command failed: {0}'.format(response['stderr'])
            )
        else:
            response = response['stdout']
    else:
        if 'Error' in response:
            raise CommandExecutionError(
                'RabbitMQ command failed: {0}'.format(response)
            )
    return {
        msg: response
    }


def check_password(name, password, runas=None):
    '''
    .. versionadded:: 2016.3.0

    Checks if a user's password is valid.

    CLI Example:

    .. code-block:: bash

        salt '*' rabbitmq.check_password rabbit_user password
    '''
    # try to get the rabbitmq-version - adapted from _get_rabbitmq_plugin

    if runas is None and not salt.utils.is_windows():
        runas = salt.utils.get_user()

    try:
        res = __salt__['cmd.run']([RABBITMQCTL, 'status'], reset_system_locale=False, runas=runas, python_shell=False)

        # Fix for PROD-35125 - rabbitmq module incompatible with rabbitmq-server 3.8+
        # https://github.com/saltstack/salt/commit/d0e0ed6b60f4de6d2b2551cad2fc7a553efe0274

        # Check regex against older RabbitMQ version status output
        old_server_version = re.search(r'\{rabbit,"RabbitMQ","(.+)"\}', res)
        # Check regex against newer RabbitMQ version status output
        server_version = re.search(r"RabbitMQ version:\s*(.+)", res)

        if server_version is None and old_server_version is None:
            raise ValueError

        if old_server_version:
            server_version = old_server_version
        server_version = server_version.group(1).split("-")[0]
        version = [int(i) for i in server_version.split(".")]

    except ValueError:
        version = (0, 0, 0)
    if len(version) < 3:
        version = (0, 0, 0)

    # rabbitmq introduced a native api to check a username and password in version 3.5.7.
    if tuple(version) >= (3, 5, 7):
        if salt.utils.is_windows():
            # On Windows, if the password contains a special character
            # such as '|', normal execution will fail. For example:
            # cmd: rabbitmq.add_user abc "asdf|def"
            # stderr: 'def' is not recognized as an internal or external
            #         command,\r\noperable program or batch file.
            # Work around this by using a shell and a quoted command.
            python_shell = True
            cmd = '"{0}" authenticate_user "{1}" "{2}"'.format(
                RABBITMQCTL, name, password
            )
        else:
            python_shell = False
            cmd = [RABBITMQCTL, 'authenticate_user', name, password]

        res = __salt__['cmd.run_all'](
            cmd,
            reset_system_locale=False,
            runas=runas,
            output_loglevel='quiet',
            python_shell=python_shell)

        if res['retcode'] != 0 or res['stderr']:
            return False
        return True

    cmd = ('rabbit_auth_backend_internal:check_user_login'
        '(<<"{0}">>, [{{password, <<"{1}">>}}]).').format(
        name.replace('"', '\\"'),
        password.replace('"', '\\"'))

    res = __salt__['cmd.run_all'](
        [RABBITMQCTL, 'eval', cmd],
        reset_system_locale=False,
        runas=runas,
        output_loglevel='quiet',
        python_shell=False)
    msg = 'password-check'

    _response = _format_response(res, msg)
    _key = _response.keys()[0]

    if 'invalid credentials' in _response[_key]:
        return False

    return True
