"""
Module to handle interaction with salt
"""
import json
import os
import time

from cfg_checker.common import config, logger, logger_cli
from cfg_checker.common.exception import InvalidReturnException, SaltException
from cfg_checker.common.other import shell

import requests


def _extract_password(_raw):
    if not isinstance(_raw, unicode):
        raise InvalidReturnException(_raw)
    else:
        try:
            _json = json.loads(_raw)
        except ValueError:
            raise SaltException(
                "# Return value is not a json: '{}'".format(_raw)
            )

    return _json["local"]


def get_remote_env_password():
    """Uses ssh call with configured options to get password from salt master

    :return: password string
    """
    _salt_cmd = "salt-call --out=json pillar.get _param:salt_api_password"
    _ssh_cmd = ["ssh"]
    # Build SSH cmd
    if config.ssh_key:
        _ssh_cmd.append("-i " + config.ssh_key)
    if config.ssh_user:
        _ssh_cmd.append(config.ssh_user+'@'+config.ssh_host)
    else:
        _ssh_cmd.append(config.ssh_host)
    if config.ssh_uses_sudo:
        _ssh_cmd.append("sudo")

    _ssh_cmd.append(_salt_cmd)
    _ssh_cmd = " ".join(_ssh_cmd)
    logger_cli.debug("... calling salt: '{}'".format(_ssh_cmd))
    _result = shell(_ssh_cmd)
    if len(_result) < 1:
        raise InvalidReturnException("# Empty value returned for '{}".format(
            _ssh_cmd
        ))
    else:
        return _extract_password(_result)


def get_local_password():
    """Calls salt locally to get password from the pillar

    :return: password string
    """
    _cmd = "salt-call --out=json pillar.get _param:salt_api_password"
    _result = shell(_cmd)
    return _extract_password(_result)


def list_to_target_string(node_list, separator):
    result = ''
    for node in node_list:
        result += node + ' ' + separator + ' '
    return result[:-(len(separator)+2)]


class SaltRest(object):
    _host = config.salt_host
    _port = config.salt_port
    uri = "http://" + config.salt_host + ":" + config.salt_port
    _auth = {}

    default_headers = {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'X-Auth-Token': None
    }

    def __init__(self):
        self._token = self._login()
        self.last_response = None

    def get(
        self,
        path='',
        headers=default_headers,
        cookies=None,
        timeout=None
    ):
        _path = os.path.join(self.uri, path)
        logger.debug("# GET '{}'\nHeaders: '{}'\nCookies: {}".format(
            _path,
            headers,
            cookies
        ))
        return requests.get(
            _path,
            headers=headers,
            cookies=cookies,
            timeout=timeout
        )

    def post(self, data, path='', headers=default_headers, cookies=None):
        if data is None:
            data = {}
        _path = os.path.join(self.uri, path)
        if path == 'login':
            _data = str(data).replace(self._pass, "*****")
        else:
            _data = data
        logger.debug(
            "# POST '{}'\nHeaders: '{}'\nCookies: {}\nBody: {}".format(
                _path,
                headers,
                cookies,
                _data
            )
        )
        return requests.post(
            os.path.join(self.uri, path),
            headers=headers,
            json=data,
            cookies=cookies
        )

    def _login(self):
        # if there is no password - try to get local, if this available
        if config.salt_env == "local":
            _pass = get_local_password()
        else:
            _pass = get_remote_env_password()
        login_payload = {
            'username': config.salt_user,
            'password': _pass,
            'eauth': 'pam'
        }
        self._pass = _pass
        logger.debug("# Logging in to salt master...")
        _response = self.post(login_payload, path='login')

        if _response.ok:
            self._auth['response'] = _response.json()['return'][0]
            self._auth['cookies'] = _response.cookies
            self.default_headers['X-Auth-Token'] = \
                self._auth['response']['token']
            return self._auth['response']['token']
        else:
            raise EnvironmentError(
                "# HTTP:{}, Not authorized?".format(_response.status_code)
            )

    def salt_request(self, fn, *args, **kwargs):
        # if token will expire in 5 min, re-login
        if self._auth['response']['expire'] < time.time() + 300:
            self._auth['response']['X-Auth-Token'] = self._login()

        _method = getattr(self, fn)
        _response = _method(*args, **kwargs)
        self.last_response = _response
        _content = "..."
        _len = len(_response.content)
        if _len < 1024:
            _content = _response.content
        logger.debug(
            "# Response (HTTP {}/{}), {}: {}".format(
                _response.status_code,
                _response.reason,
                _len,
                _content
            )
        )
        if _response.ok:
            return _response.json()['return']
        else:
            raise EnvironmentError(
                "# Salt Error: HTTP:{}, '{}'".format(
                    _response.status_code,
                    _response.reason
                )
            )


class SaltRemote(SaltRest):
    master_node = ""

    def __init__(self):
        super(SaltRemote, self).__init__()

    def cmd(
            self,
            tgt,
            fun,
            param=None,
            client='local',
            kwarg=None,
            expr_form=None,
            tgt_type=None,
            timeout=None
    ):
        _timeout = timeout if timeout is not None else config.salt_timeout
        _payload = {
            'fun': fun,
            'tgt': tgt,
            'client': client,
            'timeout': _timeout
        }

        if expr_form:
            _payload['expr_form'] = expr_form
        if tgt_type:
            _payload['tgt_type'] = tgt_type
        if param:
            _payload['arg'] = param
        if kwarg:
            _payload['kwarg'] = kwarg

        _response = self.salt_request('post', [_payload])
        if isinstance(_response, list):
            return _response[0]
        else:
            raise EnvironmentError(
                "# Unexpected response from from salt-api/LocalClient: "
                "{}".format(_response)
            )

    def run(self, fun, kwarg=None):
        _payload = {
            'client': 'runner',
            'fun': fun,
            'timeout': config.salt_timeout
        }

        if kwarg:
            _payload['kwarg'] = kwarg

        _response = self.salt_request('post', [_payload])
        if isinstance(_response, list):
            return _response[0]
        else:
            raise EnvironmentError(
                "# Unexpected response from from salt-api/RunnerClient: "
                "{}".format(_response)
            )

    def wheel(self, fun, arg=None, kwarg=None):
        _payload = {
            'client': 'wheel',
            'fun': fun,
            'timeout': config.salt_timeout
        }

        if arg:
            _payload['arg'] = arg
        if kwarg:
            _payload['kwarg'] = kwarg

        _response = self.salt_request('post', _payload)['data']
        if _response['success']:
            return _response
        else:
            raise EnvironmentError(
                "# Salt Error: '{}'".format(_response['return']))

    def pillar_request(self, node_target, pillar_submodule, argument):
        # example cli: 'salt "ctl01*" pillar.keys rsyslog'
        _type = "compound"
        if isinstance(node_target, list):
            _type = "list"
        return self.cmd(
            node_target,
            "pillar." + pillar_submodule,
            argument,
            expr_form=_type
        )

    def pillar_keys(self, node_target, argument):
        return self.pillar_request(node_target, 'keys', argument)

    def pillar_get(self, node_target, argument):
        return self.pillar_request(node_target, 'get', argument)

    def pillar_data(self, node_target, argument):
        return self.pillar_request(node_target, 'data', argument)

    def pillar_raw(self, node_target, argument):
        return self.pillar_request(node_target, 'raw', argument)

    def list_minions(self):
        """
            Fails in salt version 2016.3.8
            Works starting from 2017.7.7
            api returns dict of minions with grains
        """
        try:
            _r = self.salt_request('get', 'minions', timeout=10)
        except requests.exceptions.ReadTimeout:
            logger_cli.debug("... timeout waiting list minions from Salt API")
            _r = None
        return _r[0] if _r else None

    def list_keys(self):
        """
            Fails in salt version 2016.3.8
            Works starting from 2017.7.7
            api should return dict:
            {
                'local': [],
                'minions': [],
                'minions_denied': [],
                'minions_pre': [],
                'minions_rejected': [],
            }
        """
        return self.salt_request('get', path='keys')

    def get_status(self):
        """
            Fails in salt version 2017.7.7
            'runner' client is the equivalent of 'salt-run'
            Returns the
        """
        return self.run(
            'manage.status',
            kwarg={'timeout': 10}
        )

    def get_active_nodes(self):
        """Used when other minion list metods fail

        :return: json result from salt test.ping
        """
        if config.skip_nodes:
            logger.info("# Nodes to be skipped: {0}".format(config.skip_nodes))
            _r = self.cmd(
                '* and not ' + list_to_target_string(
                    config.skip_nodes,
                    'and not'
                ),
                'test.ping',
                expr_form='compound')
        else:
            _r = self.cmd('*', 'test.ping')
        # Return all nodes that responded
        return [node for node in _r.keys() if _r[node]]

    def get_monitoring_ip(self, param_name):
        salt_output = self.cmd(
            'docker:client:stack:monitoring',
            'pillar.get',
            param=param_name,
            expr_form='pillar')
        return salt_output[salt_output.keys()[0]]

    def f_touch_master(self, path, makedirs=True):
        _kwarg = {
            "makedirs": makedirs
        }
        salt_output = self.cmd(
            self.master_node,
            "file.touch",
            param=path,
            kwarg=_kwarg
        )
        return salt_output[salt_output.keys()[0]]

    def f_append_master(self, path, strings_list, makedirs=True):
        _kwarg = {
            "makedirs": makedirs
        }
        _args = [path]
        _args.extend(strings_list)
        salt_output = self.cmd(
            self.master_node,
            "file.write",
            param=_args,
            kwarg=_kwarg
        )
        return salt_output[salt_output.keys()[0]]

    def mkdir(self, target, path, tgt_type=None):
        salt_output = self.cmd(
            target,
            "file.mkdir",
            param=path,
            expr_form=tgt_type
        )
        return salt_output

    def f_manage_file(self, target_path, source,
                      sfn='', ret='{}',
                      source_hash={},
                      user='root', group='root', backup_mode='755',
                      show_diff='base',
                      contents='', makedirs=True):
        """
        REST variation of file.get_managed
        CLI execution goes like this (10 agrs):
        salt cfg01\\* file.manage_file /root/test_scripts/pkg_versions.py
        '' '{}' /root/diff_pkg_version.py
        '{hash_type: 'md5', 'hsum': <md5sum>}' root root '755' base ''
        makedirs=True
            param: name - target file placement when managed
            param: source - source for the file
        """
        _source_hash = {
            "hash_type": "md5",
            "hsum": 000
        }
        _arg = [
            target_path,
            sfn,
            ret,
            source,
            _source_hash,
            user,
            group,
            backup_mode,
            show_diff,
            contents
        ]
        _kwarg = {
            "makedirs": makedirs
        }
        salt_output = self.cmd(
            self.master_node,
            "file.manage_file",
            param=_arg,
            kwarg=_kwarg
        )
        return salt_output[salt_output.keys()[0]]

    def cache_file(self, target, source_path):
        salt_output = self.cmd(
            target,
            "cp.cache_file",
            param=source_path
        )
        return salt_output[salt_output.keys()[0]]

    def get_file(self, target, source_path, target_path, tgt_type=None):
        return self.cmd(
            target,
            "cp.get_file",
            param=[source_path, target_path],
            expr_form=tgt_type
        )

    @staticmethod
    def compound_string_from_list(nodes_list):
        return " or ".join(nodes_list)
