# -*- coding: utf-8 -*-
import re
from utils.business.project_condition_utils import get_project_condition_boolean
from utils.common.exception import HCCIException
from utils.DBAdapter.DBConnector import BaseOps
from utils.common.PublicServiceOperate import ParameterQuery
from utils.common.fic_base import StepBaseInterface
from utils.common.fic_base import TestCase
from utils.common.message import Message
from utils.common.ssh_util import Ssh as ssh
import utils.common.log as logger


class ExecCmd():
    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 HCCIException 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 HCCIException 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 reinforce_system(self, ssh_client, host_ip):
        cmd_items = ["/opt/reinforce_os/reinforce_os.sh install >/dev/null", "echo last_code=$?"]
        cmds = ";".join(cmd_items)
        cmd_ret = None
        try:
            cmd_ret = ssh.ssh_send_command(ssh_client, cmds, "#", 60, 3)
            logger.info("exe cmd[%s] result:%s" % (cmds, str(cmd_ret)))
            cmd_ret = str(cmd_ret)
            if 0 > cmd_ret.find('last_code=0'):
                err_msg = "Failed to run reinforce system scrpts on host[%s], Detail:%s" % (host_ip, cmd_ret)
                logger.error(err_msg)
                raise Exception('last execute code is not 0')
        except Exception as e:
            logger.error("Failed to run reinforce system scrpts on host[%s], error detail:%s, "
                         "cmd_result:%s" % (host_ip, str(e), str(cmd_ret)))
            return False
        logger.info('Success to to open root privilege, omip:%s.' % (host_ip))
        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 Do_OS_Check(TestCase):
    def __init__(self, project_id, pod_id):
        super(Do_OS_Check, self).__init__(project_id, pod_id)
        self.project_id = project_id
        self.pod_id = pod_id
        self.sshObj = ssh()
        self.db = BaseOps()
        self.args_dict = {
            "project_id": project_id,
            "pod_id": pod_id
        }

    def procedure(self):

        """
        检查存储节点的内存
       """
        try:
            # 查询storage node 的IP、用户名、密码
            bmc_info_lists = self.db.get_install_os_list_info(self.pod_id, "rep")
            fsm_query = ParameterQuery("DistributedStorage", self.args_dict)
            fsadmin_pwd = fsm_query.get_value_from_cloudparam("FSMfsdminPassword")
            fsadmin_fail_list = list()
            switch_fail_list = list()
            language_fail_list = list()
            reenforce_fail_list = list()
            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]
                self.exec_obj = ExecCmd()
                client = self.exec_obj.create_client(datamover_ip, creuser_info[2], creuser_info[3])
                # 检查切root
                self.check_switch_root(client, creuser_info, switch_fail_list, datamover_ip, reenforce_fail_list)
                # 检查语言
                self.check_language(client, language_fail_list, datamover_ip)

                self.exec_obj.close_client(client)

                # 校验fsadmin用户可登陆性
                self.check_fsadmin_login(datamover_ip, fsadmin_pwd, fsadmin_fail_list)

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

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

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

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

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

            logger.info("[FSBR] Check switch root success")
            return True, None
        except HCCIException as e1:
            logger.error(e1)
            raise e1
        except Exception as e2:
            logger.error(e2)
            raise e2

    def check_switch_root(self, client, creuser_info, switch_fail_list, datamover_ip, reenforce_fail_list):
        result = self.exec_obj.check_switch_root(client, creuser_info[1])
        if not result:
            switch_fail_list.append(datamover_ip)
        else:
            if get_project_condition_boolean(
                    self.project_id,
                    'DRStorage_TFB_Sep&(CSHAStorage_TFB|CSDRStorage_TFB)&!TenantStorFB_Heterogeneous'):
                # 自动化装机后执行安全加固
                rsp_reinforce = self.exec_obj.reinforce_system(client, datamover_ip)
                if not rsp_reinforce:
                    reenforce_fail_list.append(datamover_ip)

        if client['channel'].closed:
            client = self.exec_obj.create_client(datamover_ip, creuser_info[2], creuser_info[3])
            self.exec_obj.check_switch_root(client, creuser_info[1])

    def check_language(self, client, language_fail_list, datamover_ip):
        result = self.exec_obj.check_language(client)
        if not result:
            language_fail_list.append(datamover_ip)

    def check_fsadmin_login(self, datamover_ip, fsadmin_pwd, fsadmin_fail_list):
        try:
            client = self.exec_obj.create_client(datamover_ip, 'fsadmin', fsadmin_pwd)
        except Exception as error:
            logger.error('Error:{}'.format(error))
            fsadmin_fail_list.append(datamover_ip)
        else:
            self.exec_obj.close_client(client)

    def post_condition(self):
        return Message(200)

    def failure(self):
        super(Do_OS_Check, self).failure()
        # 环境恢复脚本


class ReplicationOSCheck(StepBaseInterface):
    def __init__(self, project_id, pod_id):
        super(ReplicationOSCheck, self).__init__(project_id, pod_id)
        self.project_id = project_id
        self.pod_id = pod_id
        self.db = BaseOps()

    def pre_check(self, project_id, pod_id):
        """
        插件内部接口：执行安装前的资源预检查，该接口由execute接口调用，工具框架不会直接调用此接口。
        :param project_id:
        :param pod_id:
        :return:
        """
        pass

    def execute(self, project_id, pod_id):
        try:
            self.implement = Do_OS_Check(project_id, pod_id)
            self.implement.procedure()
            return Message(200)
        except HCCIException as e1:
            return Message(500, e1)
        except Exception as e2:
            return Message(500, HCCIException('627410', str(e2)))

    def rollback(self, project_id, pod_id):
        """
        标准调用接口：执行回滚
        :param project_id:
        :param pod_id:
        :return:Message类对象
        """
        return Message(200)

    def retry(self, project_id, pod_id):
        """
        标准调用接口：重试
        :return: Message类对象
        """
        return self.execute(project_id, pod_id)

    def check(self, project_id, pod_id):
        """
        标准调用接口：重试
        :param project_id:
        :param pod_id:
        :return:
        """
        pass
