# -*- coding: UTF-8 -*-
import re
import utils.common.log as logger
from utils.common.exception import FCDException
from utils.common.fic_base import StepBaseInterface
from utils.common.ssh_util import Ssh as ssh
from plugins.DistributedStorage.scripts.utils.common.SeparateStorageNode_Check_Network import get_bmc_ip


class ExecCmd:
    @classmethod
    def check_fsadmin(cls, client):
        cmd = "id fsadmin;echo last_result=$?"
        resp = ssh.ssh_exec_command_return(client, cmd, retry_times=3)
        return str(resp).__contains__("last_result=0")

    def check_switch_root(self, client, root_pwd):
        try:
            ssh.ssh_send_command(client, "su - root", "Password:", timeout=30)
            ssh.ssh_send_command(client, root_pwd, "#", timeout=30)
            return True
        except FCDException as e:
            client.clear()
            logger.error("Switch root fail. Not get expected output,detail: %s" % str(e))
            return False

    def check_language(self, client):
        try:
            pattern = re.compile("zh_CN")
            cmd = "echo $LANG"
            resp = ssh.ssh_exec_command_return(client, cmd, retry_times=3)
            result = ''.join(resp)
            logger.info("[FSBR] exec command success. detail:%s" % result)
            if pattern.findall(result):
                return False
            return True
        except FCDException as e:
            logger.error("[FSBR] Check language fail.detail: %s" % str(e))
            return False

    def open_root_access(self, ssh_client, host_ip):
        cmd_items = ["sed -i \"s/PermitRootLogin.*/PermitRootLogin yes/g\" /etc/ssh/sshd_config",
                     "grep -q -w \"AllowUsers.*root\" /etc/ssh/sshd_config || "
                     "sed -i 's/AllowUsers.*/& root/' /etc/ssh/sshd_config",
                     "grep -q -w \"AllowGroups.*root\" /etc/ssh/sshd_config || "
                     "sed -i 's/AllowGroups.*/& root/' /etc/ssh/sshd_config",
                     "service sshd restart"]
        open_cmds = ";".join(cmd_items)
        cmd_res = None
        try:
            cmd_res = ssh.ssh_send_command(ssh_client, open_cmds, "#", 60, 3)
            logger.info("exe cmd[%s] result:%s" % (open_cmds, str(cmd_res)))
        except Exception as e:
            logger.error("Failed to open root privilege, omip:%s, err:%s, cmd_result:%s" % (host_ip, str(e),
                                                                                            str(cmd_res)))
            if ssh_client:
                ssh.ssh_close(ssh_client)
        logger.info('Success to to open root privilege, omip:%s.' % (host_ip))
        if ssh_client:
            ssh.ssh_close(ssh_client)
        return True

    def create_client(self, host_ip, username, passwd):
        return ssh.ssh_create_client(host_ip, username, passwd)

    def close_client(self, client):
        ssh.ssh_close(client)


class SystemCheck(StepBaseInterface):
    def __init__(self, project_id, pod_id, db):
        super(SystemCheck, self).__init__(project_id, pod_id)
        self.project_id = project_id
        self.pod_id = pod_id
        self.sshObj = ssh()
        self.db = db
        self.args_dict = {
            "project_id": project_id,
            "pod_id": pod_id
        }
        self.fsadmin_fail_list = list()
        self.switch_fail_list = list()
        self.language_fail_list = list()
        self.reenforce_fail_list = list()
        self.bmc_confirm_fail_list = list()

    def procedure(self):
        bmc_info_lists = self.db.get_install_os_list_info(self.pod_id)
        for bmc_info in bmc_info_lists:
            logger.info("bmc_ip:%s Mem check" % bmc_info['bmc_ip'])
            creuser_info = bmc_info['creuser'].split(',')
            datamover_ip = bmc_info["manageIp"].split("/")[0]
            exec_obj = ExecCmd()
            client = exec_obj.create_client(datamover_ip, creuser_info[2], creuser_info[3])
            # 检查切root
            result = exec_obj.check_switch_root(client, creuser_info[1])
            if not result:
                self.switch_fail_list.append(datamover_ip)
            else:
                self._check_bmc_ip_consistent(bmc_info, client)
            if client['channel'].closed:
                client = exec_obj.create_client(datamover_ip, creuser_info[2], creuser_info[3])
                exec_obj.check_switch_root(client, creuser_info[1])
            # 检查语言
            logger.info("Check the language configuration of the node:[{}]".format(datamover_ip))
            result = exec_obj.check_language(client)
            if not result:
                self.language_fail_list.append(datamover_ip)
            logger.info("Check whether the fsadmin user exists on the node:[{}]".format(datamover_ip))
            result = exec_obj.check_fsadmin(client)
            if not result:
                self.fsadmin_fail_list.append(datamover_ip)
            exec_obj.close_client(client)

        self.error_msg_handle()
        logger.info("Finish to check and config configuration items on all host")

    def _check_bmc_ip_consistent(self, bmc_info, client):
        """
        切root成功后，才能检查目标节点一致性
        """
        current_node_bmc_ip = get_bmc_ip(client)
        target_node_bmc_ip = bmc_info["bmc_ip"]
        logger.info("This is the current node BMC IP[%s] "
                    "and the target node BMC IP[%s]." % (current_node_bmc_ip, target_node_bmc_ip))
        # 检查节点BMC IP是否与目标节点一致
        if current_node_bmc_ip != target_node_bmc_ip:
            err_msg = "The BMC IP[%s] of the current node is inconsistent with the BMC IP[%s] of the node" \
                      " in the installation system." % (current_node_bmc_ip, target_node_bmc_ip)
            logger.info(err_msg)
            self.bmc_confirm_fail_list.append((current_node_bmc_ip, target_node_bmc_ip))

    def error_msg_handle(self):
        if self.bmc_confirm_fail_list:
            curr_bmc_list = list()
            target_bmc_list = list()
            for curr_bmc, target_bmc in self.bmc_confirm_fail_list:
                curr_bmc_list.append(curr_bmc)
                target_bmc_list.append(target_bmc)
            current_bmc = ','.join(curr_bmc_list)
            target_bmc = ','.join(target_bmc_list)
            raise FCDException(626107, current_bmc, target_bmc)

        if self.language_fail_list and self.switch_fail_list:
            msg = "[FSBR] Check switch root and language fail.detail: switch fail list:%s,language fail list: %s" \
                  % (self.switch_fail_list, self.language_fail_list)
            logger.error(msg)
            raise FCDException(626042, str(self.switch_fail_list), str(self.language_fail_list))

        if self.switch_fail_list:
            logger.error("[FSBR] check switch root fail,fail list: %s" % str(self.switch_fail_list))
            raise FCDException(626041, str(self.switch_fail_list))

        if self.language_fail_list:
            logger.error("[FSBR] check system default language fail,fail list: %s" % str(self.language_fail_list))
            raise FCDException(626043, str(self.language_fail_list))

        if self.reenforce_fail_list:
            logger.error("[FSBR] Failed to run reinforce system scrpts on host%s" % self.reenforce_fail_list)
            raise FCDException(626089, str(self.reenforce_fail_list))

        if self.fsadmin_fail_list:
            logger.error("[FSBR] Failed to login with username <fsadmin> on hosts[%s]" % self.fsadmin_fail_list)
            raise FCDException(626334, str(self.fsadmin_fail_list))
