#    Copyright 2016 Mirantis, Inc.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.
from tcp_tests import logger
from tcp_tests.managers.execute_commands import ExecuteCommandsMixin

LOG = logger.logger


class ReclassManager(ExecuteCommandsMixin):
    """docstring for ReclassManager"""

    __config = None
    __underlay = None
    reclass_tools_cmd = ". venv-reclass-tools/bin/activate; reclass-tools "
    tgt = "cfg01"  # place where the reclass-tools installed

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

        reclass_node = [node_name
                        for node_name in self.__underlay.node_names()
                        if self.tgt in node_name]
        self.ssh = self.__underlay.remote(node_name=reclass_node[0])

        super(ReclassManager, self).__init__(config=config, underlay=underlay)

    def check_existence(self, key):
        """
        Returns True if reclass contains that key.
        :param key: string
        :return: boolean
        """
        if key in self.ssh.check_call(
                "{reclass_tools} get-key {key} /srv/salt/reclass/classes".
                format(reclass_tools=self.reclass_tools_cmd,
                       key=key)):
            LOG.warning("({}) key already exists in reclass".format(key))
            return True
        return False

    def add_key(self, key, value, short_path):
        """
        Shows alert if key exists

        :param key: string, parameters which will be added or updated
        :param value: value of key
        :param short_path: path to reclass yaml file.
            It takes into account default path where the reclass locates.
            May look like cluster/*/cicd/control/leader.yml
        :return: None
        """

        value = str(value).replace('"', "'")
        # let's escape $ symbol for bash-like command
        value = str(value).replace("$", r"\$")

        # value can contain a space symbol. So value should be in quotes
        cmd = "{reclass_tools} add-key {key} \"{value}\" \
            /srv/salt/reclass/classes/{path}".format(
                reclass_tools=self.reclass_tools_cmd,
                key=key,
                value=value,
                path=short_path)
        LOG.info("Add key to reclass: \n  {cmd} ".format(cmd=cmd))
        self.ssh.check_call(cmd)

    def get_key(self, key, file_name):
        """Find a key in a YAML

        :param key: string, parameter to add
        :param file_name: name of YAML file to find a key
        :return: str, key if found
        """
        LOG.info("Try to get '{key}' key from '{file}' file".format(
            file=file_name,
            key=key
            ))
        request_key = self.ssh.check_call(
            "{reclass_tools} get-key {key} /srv/salt/reclass/*/{file_name}".
            format(reclass_tools=self.reclass_tools_cmd,
                   key=key,
                   file_name=file_name))['stdout']

        # Reclass-tools returns result to stdout, so we get it as
        #     ['\n',
        #      '---\n',
        #      '# Found parameters._param.jenkins_pipelines_branch in \
        #          /srv/salt/reclass/classes/cluster/../infra/init.yml\n',
        #      'release/proposed/2019.2.0\n',
        #      '...\n',
        #      '\n']
        # So we have no chance to get value without dirty code like `stdout[3]`

        LOG.info("Raw output from reclass.get_key {}".format(request_key))
        if len(request_key) < 4:
            print("Can't find {key} in {file_name}. Got stdout {stdout}".
                  format(key=key,
                         file_name=file_name,
                         stdout=request_key))
            return None
        value = request_key[3].strip('\n')
        LOG.info("From reclass.get_key {}".format(value))
        return value

    def add_bool_key(self, key, value, short_path):
        """
        Shows alert if key exists

        :param key: string, parameters which will be added or updated
        :param value: value of key
        :param short_path: path to reclass yaml file.
            It takes into account default path where the reclass locates.
            May look like cluster/*/cicd/control/leader.yml
        :return: None
        """
        self.check_existence(key)
        self.ssh.check_call(
            "{reclass_tools} add-bool-key {key} {value} \
            /srv/salt/reclass/classes/{path}".format(
                reclass_tools=self.reclass_tools_cmd,
                key=key,
                value=value,
                path=short_path
            ), raise_on_err=False)

    def add_class(self, value, short_path):
        """
        Shows warning if class exists
        :param value: role to add to 'classes' parameter in the reclass
        :param short_path: path to reclass yaml file.
            It takes into account default path where the reclass locates.
            May look like cluster/*/cicd/control/leader.yml
        :return: None
        """
        if value in self.ssh.check_call(
                "{reclass_tools} get-key classes \
                /srv/salt/reclass/classes/{path}".format(
                    reclass_tools=self.reclass_tools_cmd,
                    value=value,
                    path=short_path
                )):
            LOG.warning("Class {} already exists in {}".format(
                value,
                short_path
            ))

        self.ssh.check_call(
            "{reclass_tools} add-key classes {value} \
            /srv/salt/reclass/classes/{path} --merge".format(
                reclass_tools=self.reclass_tools_cmd,
                value=value,
                path=short_path
            ))

    def delete_key(self, key, short_path):
        """
        Remove key from the provided file

        :param value: string, parameter which will be deleted
        :param short_path: string,, path to reclass yaml file.
            It takes into account default path where the reclass locates.
            May look like cluster/*/cicd/control/leader.yml
        :return: None
        """
        self.ssh.check_call(
            "{reclass_tools} del-key {key} \
            /srv/salt/reclass/classes/{path}".format(
                reclass_tools=self.reclass_tools_cmd,
                key=key,
                path=short_path
            ))

    def commit(self, text_commit):
        self.ssh.check_call(
            "cd /srv/salt/reclass; git add -u && git commit --allow-empty "
            "-m '{text}'".format(text=text_commit))
