
import time

from tcp_tests import logger
from tcp_tests.helpers.log_helpers import pretty_repr

LOG = logger.logger


class ExecuteCommandsMixin(object):
    """docstring for ExecuteCommands"""

    __config = None
    __underlay = None

    def __init__(self, config, underlay):
        self.__config = config
        self.__underlay = underlay
        super(ExecuteCommandsMixin, self).__init__()

    def execute_commands(self, commands, label="Command"):
        """Execute a sequence of commands

        Main propose is to implement workarounds for salt formulas like:
        - exit_code == 0 when there are actual failures
        - salt_master and/or salt_minion stop working after executing a formula
        - a formula fails at first run, but completes at next runs

        :param label: label of the current sequence of the commands, for log
        :param commands: list of dicts with the following data:
        commands = [
            ...
            {
                # Required:
                'cmd': 'shell command(s) to run',
                'node_name': 'name of the node to run the command(s)',
                # Optional:
                'description': 'string with a readable command description',
                'retry': {
                    'count': int,  # How many times should be run the command
                                   # until success
                    'delay': int,  # Delay between tries in seconds
                },
                'skip_fail': bool  # If True - continue with the next step
                                   # without failure even if count number
                                   # is reached.
                                   # If False - rise an exception (default)
            },
            ...
        ]
        """
        for n, step in enumerate(commands):
            # Required fields
            action_cmd = step.get('cmd')
            action_do = step.get('do')
            action_upload = step.get('upload')
            action_download = step.get('download')
            # node_name = step.get('node_name')
            # Optional fields
            description = step.get('description', action_cmd)
            # retry = step.get('retry', {'count': 1, 'delay': 1})
            # retry_count = retry.get('count', 1)
            # retry_delay = retry.get('delay', 1)
            # skip_fail = step.get('skip_fail', False)

            msg = "[ {0} #{1} ] {2}".format(label, n + 1, description)
            log_msg = "\n\n{0}\n{1}".format(msg, '=' * len(msg))

            if action_cmd:
                self.execute_command(step, msg)
            elif action_do:
                self.command2(step, msg)
            elif action_upload:
                LOG.info(log_msg)
                self.action_upload(step)
            elif action_download:
                LOG.info(log_msg)
                self.action_download(step)

    def execute_command(self, step, msg, return_res=None):
        # Required fields
        cmd = step.get('cmd')
        node_name = step.get('node_name')
        # Optional fields
        description = step.get('description', cmd)
        retry = step.get('retry', {'count': 1, 'delay': 1})
        retry_count = retry.get('count', 1)
        retry_delay = retry.get('delay', 1)
        skip_fail = step.get('skip_fail', False)
        timeout = step.get('timeout', None)

        with self.__underlay.remote(node_name=node_name) as remote:

            for x in range(retry_count, 0, -1):
                time.sleep(3)

                retry_msg = (' (try {0} of {1}, skip_fail={2}, node_name={3})'
                             .format(retry_count - x + 1,
                                     retry_count,
                                     skip_fail,
                                     node_name))
                LOG.info("\n\n{0}\n{1}".format(
                    msg + retry_msg, '=' * len(msg + retry_msg)))

                result = remote.execute(cmd, timeout=timeout, verbose=True)
                if return_res:
                    return result

                # Workaround of exit code 0 from salt in case of failures
                failed = 0
                for s in result['stdout'] + result['stderr']:
                    if s.startswith("Failed:"):
                        failed += int(s.split("Failed:")[1])
                    if 'Minion did not return. [No response]' in s:
                        failed += 1
                    if 'Minion did not return. [Not connected]' in s:
                        failed += 1
                    if ('Salt request timed out. The master is not responding.'
                            in s):
                        failed += 1
                    if s.startswith("[CRITICAL]"):
                        failed += 1
                    if 'Fatal' in s:
                        failed += 1

                if result.exit_code != 0:
                    time.sleep(retry_delay)
                elif failed != 0:
                    LOG.error(
                        " === SALT returned exit code = 0 while "
                        "there are failed modules! ===")
                    time.sleep(retry_delay)
                else:
                    break

                if x == 1 and skip_fail is False:
                    # In the last retry iteration, raise an exception
                    raise Exception("Step '{0}' failed:\n"
                                    "=============== Command: ==============\n"
                                    "{1}\n"
                                    "=============== STDOUT: ===============\n"
                                    "{2}\n"
                                    "=============== STDERR: ===============\n"
                                    "{3}\n"
                                    .format(description,
                                            cmd,
                                            result.stdout_str,
                                            result.stderr_str))

    def command2(self, step, msg):
        # Required fields
        do = step['do']
        target = step['target']
        state = step.get('state')
        states = step.get('states')
        # Optional fields
        args = step.get('args')
        kwargs = step.get('kwargs')
        description = step.get('description', do)
        retry = step.get('retry', {'count': 1, 'delay': 1})
        retry_count = retry.get('count', 1)
        retry_delay = retry.get('delay', 1)
        skip_fail = step.get('skip_fail', False)
        timeout = step.get('timeout', None)

        if not bool(state) ^ bool(states):
            raise ValueError("You should use state or states in step")

        for x in range(retry_count, 0, -1):
            time.sleep(3)

            retry_msg = (' (try {0} of {1}, skip_fail={2}, target={3})'
                         .format(retry_count - x + 1,
                                 retry_count,
                                 skip_fail,
                                 target))
            LOG.info("\n\n{0}\n{1}".format(
                msg + retry_msg, '=' * len(msg + retry_msg)))

            method = getattr(self._salt, self._salt._map[do])
            command_ret = method(tgt=target, state=state or states,
                                 args=args, kwargs=kwargs, timeout=timeout)
            command_ret = command_ret if \
                isinstance(command_ret, list) else [command_ret]
            results = [(r['return'][0], f) for r, f in command_ret]

            # FIMME: Change to debug level
            LOG.info(" === States output =======================\n"
                     "{}\n"
                     " =========================================".format(
                         pretty_repr([r for r, f in results])))

            all_fails = [f for r, f in results if f]
            if all_fails:
                LOG.error("States finished with failures.\n{}".format(
                    all_fails))
                time.sleep(retry_delay)
            else:
                break

            if x == 1 and skip_fail is False:
                # In the last retry iteration, raise an exception
                raise Exception("Step '{0}' failed"
                                .format(description))

    def action_upload(self, step):
        """Upload from local host to environment node

        Example:

        - description: Upload a file
          upload:
            local_path: /tmp/
            local_filename: cirros*.iso
            remote_path: /tmp/
          node_name: ctl01
          skip_fail: False
        """
        node_name = step.get('node_name')
        local_path = step.get('upload', {}).get('local_path', None)
        local_filename = step.get('upload', {}).get('local_filename', None)
        remote_path = step.get('upload', {}).get('remote_path', None)
        description = step.get('description', local_path)
        skip_fail = step.get('skip_fail', False)

        if not local_path or not remote_path:
            raise Exception("Step '{0}' failed: please specify 'local_path', "
                            "'local_filename' and 'remote_path' correctly"
                            .format(description))

        if not local_filename:
            # If local_path is not specified then uploading a directory
            with self.__underlay.remote(node_name=node_name) as remote:
                LOG.info("Uploading directory {0} to {1}:{2}"
                         .format(local_path, node_name, remote_path))
                remote.upload(source=local_path.rstrip(),
                              target=remote_path.rstrip())
                return

        result = {}
        with self.__underlay.local() as local:
            result = local.execute('cd {0} && find . -maxdepth 1 -type f'
                                   ' -name "{1}"'
                                   .format(local_path, local_filename))
            LOG.info("Found files to upload:\n{0}".format(result))

        if not result['stdout'] and not skip_fail:
            raise Exception("Nothing to upload on step {0}"
                            .format(description))

        with self.__underlay.remote(node_name=node_name) as remote:
            file_names = result['stdout']
            for file_name in file_names:
                source_path = local_path + file_name.rstrip()
                destination_path = remote_path.rstrip() + file_name.rstrip()
                LOG.info("Uploading file {0} to {1}:{2}"
                         .format(source_path, node_name, remote_path))
                remote.upload(source=source_path, target=destination_path)

    def action_download(self, step):
        """Download from environment node to local host

        Example:

        - description: Download a file
          download:
            remote_path: /tmp/
            remote_filename: report*.html
            local_path: /tmp/
          node_name: ctl01
          skip_fail: False
        """
        node_name = step.get('node_name')
        remote_path = step.get('download', {}).get('remote_path', None)
        remote_filename = step.get('download', {}).get('remote_filename', None)
        local_path = step.get('download', {}).get('local_path', None)
        description = step.get('description', remote_path)
        skip_fail = step.get('skip_fail', False)

        if not remote_path or not remote_filename or not local_path:
            raise Exception("Step '{0}' failed: please specify 'remote_path', "
                            "'remote_filename' and 'local_path' correctly"
                            .format(description))

        with self.__underlay.remote(node_name=node_name) as remote:

            result = remote.execute('find {0} -maxdepth 1 -type f -name {1}'
                                    .format(remote_path, remote_filename))
            LOG.info("Found files to download:\n{0}".format(result))

            if not result['stdout'] and not skip_fail:
                raise Exception("Nothing to download on step {0}"
                                .format(description))

            file_names = result['stdout']
            for file_name in file_names:
                LOG.info("Downloading {0}:{1} to {2}"
                         .format(node_name, file_name, local_path))
                remote.download(destination=file_name.rstrip(),
                                target=local_path)
