# -*- coding: UTF-8 -*-
from cbb.frame.cli import cliUtil
from cbb.frame.ruleConfig import common
from cbb.frame.context import contextUtil
from cbb.frame.tlv import tlvUtil
from cbb.frame.tlv import tlvData
from com.huawei.ism.tool.obase.exception import ToolException
import traceback
from service.func_utils import execute_tlv


class ControllerStatus:
    def __init__(self, data_dict):
        """
        初始化
        :param data_dict: 上下文
        """
        self.all_ret_list = list()
        self.error_msg_list = list()
        self.data_dict = data_dict
        self.log = common.getLogger(contextUtil.getLogger(data_dict), __file__)
        self.lang = data_dict.get("lang")

    def get_result(self):
        """
        获取结果
        :return:
        """
        return (
            self.check_controller_status(),
            "\n".join(self.error_msg_list),
            "\n".join(self.all_ret_list),
        )

    def check_controller_status(self):
        """
        检查控制器是否为双控的主体方法
        :return: 是否引擎为双控
        """
        try:
            flag = True
            self.add_cli_ret()
            tlv = contextUtil.getTlv(self.data_dict)
            checkItem = "CHECK_SOFTWARE_DOUBLECTRL"
            itemDict = tlvData.UPD_CHECK_RESULT[checkItem]

            try:
                self.log.logExecCmd(checkItem)
                # 根据检查项获取配置字典值
                recs = tlvUtil.get_upgrade_records(tlv, checkItem)
                self.log.logInfo("records={}".format(recs))
                return self.check_recs_by_rest(flag, itemDict, recs)
            except (ToolException, Exception) as e:
                self.log.logException(e)
                self.log.logError(
                    "sys isalldoublectrl.. by rest except:{}. use tlv".format(
                        traceback.format_exc()
                    )
                )
                # 命令层名兼容rest和tlv。当老版本不支持rest时，使用tlv。
                if e.args and "-1" in str(e.args[0]):
                    cmd = "sys isalldoublectrl"
                    return self.check_controller_status_by_tlv(cmd)

        except (ToolException, Exception) as e:
            self.log.logException(e)
            error_id = "login.clis.overrun.info" if "PwdCLIOverrunException" in str(e) else "query.result.abnormal"
            self.error_msg_list.append(common.getMsg(self.lang, error_id))
            return False

    def add_cli_ret(self):
        # 获取cli回显，保存在cliRetList
        cli = contextUtil.getCli(self.data_dict)
        cmdList = list()
        cmdList.append("sys showcls")
        cliRetList = cliUtil.GetCliRecsInDebugMode(
            cli, cmdList, self.log, self.lang
        )
        self.all_ret_list.extend(cliRetList)

    def check_recs_by_rest(self, flag, itemDict, recs):
        """

        :param flag:是否通过
        :param itemDict:
        :param recs:
        :return:
        """
        for record in recs:
            nodeId = tlvUtil.getRecordValue(
                record, tlvData.CMO_UPD_EXECUTE_DEFINE["NODE_ID"]
            )
            result = tlvUtil.getRecordValue(
                record, tlvData.CMO_UPD_EXECUTE_DEFINE["RESULT"]
            )
            # 根据模块返回值获取对应的字典值,如果失败返回None
            itemVal = itemDict.get(result, None)
            if itemVal is None:
                self.error_msg_list.append(
                    common.getMsg(self.lang, "query.result.abnormal")
                )
                flag = False
                continue
            status = itemVal.get("status", None)
            if status is True:
                continue
            flag = False
            self.error_msg_list.append(
                common.getMsg(self.lang, itemVal["msg"], nodeId)
            )
        return flag

    def check_controller_status_by_tlv(self, cmd):
        """
        用TLV检查系统是否为双控
        :param cmd: sys isalldoublectrl
        :return: True 为双控， False 不为双控
        """
        recs = execute_tlv(self.data_dict, cmd, 2)
        if not recs:
            self.log.error("[controller_status_check]records is none")
            msg = cliUtil.getMsg(self.lang, "controller.status.check.error")
            self.error_msg_list.append(msg)
            return False
        self.log.logInfo("records={}".format(recs))
        for rec in recs:
            node_id = rec.getParamStrValue(0)
            result = rec.getParamStrValue(1)
            if result == "TimeOut":
                self.error_msg_list.append(
                    cliUtil.getMsg(
                        self.lang, "controller.status.timeout", node_id
                    )
                )
                return False
            if not result:
                return False
            if "False" in result.encode("utf-8"):
                self.log.logError("check controller not pass")
                return False
        return True
