# -*- coding: UTF-8 -*-
import re
import time
from resource.resource import MESSAGES_DICT
from cbb.frame.cli import cliUtil
from cbb.frame.context import contextUtil
from cbb.frame.base import baseUtil


def execute(data_dict):
    """
    :功能描述: 检查电源升级状态
    """

    check_item = CheckPowerUpgradeState(data_dict)
    result = check_item.execute()
    if not result:
        return False, "\n".join(check_item.msg_list), ""
    return True, "", ""


VER_DICT = {
    '6.0.1': 'SPH35', '6.1.0': 'SPH27', '6.1.2': 'SPH30', '6.1.3': 'SPH10', '6.1.5': 'SPH8',
    'V500R007C60SPC100': 'V500R007C60SPH111',
    'V500R007C60SPC300': 'V500R007C60SPH330',
    'V500R007C70SPC200': 'V500R007C70SPH210',
    'V500R007C71SPC100': 'V500R007C71SPH130',
    'V500R007C73SPC100': 'V500R007C73SPH110',
}

PRODUCT_MODEL_H = [
    "OceanStor Dorado 8000 V6", "OceanStor Dorado 18000 V6", "OceanStor Dorado 6800 V6",
    "OceanStor Dorado 18500 V6", "OceanStor Dorado 18800 V6", "OceanStor Dorado 18800K V6",
    "OceanStor 6810", "OceanStor 18510", "OceanStor 18500K", "OceanStor 18810",
    "6800 V5", "6800F V5", "6800K V5", "6810 V5", "6810F V5", "18500 V5", "18500F V5", "18500K V5",
    "18510 V5", "18510F V5", "18800 V5", "18800F V5", "18800K V5", "18810 V5", "18810F V5",
]


class CheckPowerUpgradeState:
    def __init__(self, data_dict):
        self.data_dict = data_dict
        self.cli = contextUtil.getCli(data_dict)
        self.logger = contextUtil.getLogger(data_dict)
        self.lang = contextUtil.getLang(data_dict)
        self.dev = self.data_dict.get("dev")
        self.dev_type = str(self.dev.getDeviceType())
        self.msg_list = []

    def execute(self):
        flag, software_version, hotpatch_version, cli_ret = cliUtil.get_system_version_with_ret(self.cli, self.lang)
        log_info = "software version: {}, hotpatch version: {}".format(software_version, hotpatch_version)
        self.logger.info(log_info)
        
        if software_version not in VER_DICT: # 版本
            return True
        result = compare_patch_version(hotpatch_version, VER_DICT.get(software_version)) # 补丁
        if result < 0:
            return True
        if self.check_psu_target(software_version):
            return True
        
        self.ssh_to_0_node()
        is_exist_permit = self.check_file_exist("power_upgrade_permit")
        is_exist_prohibit = self.check_file_exist("power_upgrade_prohibit")
        if is_exist_permit:
            if is_exist_prohibit:
                return True
            self.msg_list.append(self.get_msg("power.patch.upgrade.suggestion"))
            self.logger.info("The power supply is being upgrading.")
            return False
        return True

    # 检查存在psu_model为PAC2000S12-BG，且psu_verdc = 111/113/115/119的电源
    def check_psu_target(self, software_ver):
        cli_cmd = "show power_supply|filterColumn include columnList=ID,Version,Model,Serial\sNumber"
        _, cli_ret, _ = cliUtil.execCmdInCliMode(self.cli, cli_cmd, True, self.lang)
        psu_list = cliUtil.getHorizontalCliRet(cli_ret)
        for psu_info in psu_list:
            psu_id = psu_info.get("ID", "")
            psu_model = psu_info.get("Model", "")
            psu_verdc = psu_info.get("Version", "")
            if "CTE" in psu_id and self.dev_type in PRODUCT_MODEL_H: # 高端控制框PSU不识别风险电源
                continue
            # 存在需要升级psu，psu_model为PAC2000S12-BG，且psu_verdc = 111/113/115/119
            if psu_model == "PAC2000S12-BG":
                if software_ver in ['6.0.1', 'V500R007C60SPC100', 'V500R007C60SPC300']:
                    return False
                if psu_verdc != "" and psu_verdc.split(".")[0] in ['111', '113', '115', '119']:
                    return False
        return True # 不存在需要升级psu

    def check_file_exist(self, filename):
        cmd = "ls /startup_disk/conf/conf_local/"
        is_suc, cli_conf, err_msg = cliUtil.excuteCmdInMinisystemModel(self.cli, cmd, self.lang)
        is_suc, cli_tmp, err_msg = cliUtil.excuteCmdInMinisystemModel(self.cli, "ls /tmp/", self.lang)
        if filename in cli_conf or filename in cli_tmp:
            return True
        return False
    
    def get_msg(self, msg_key):
        return baseUtil.getPyResource(self.lang, msg_key, "", resource=MESSAGES_DICT)
    
    def ssh_to_0_node(self):
        password = self.dev.getLoginUser().getPassword()
        for _ in range(5):
            cmd = "sshtoremoteExt 0"
            is_succ, cli_ret, _ = cliUtil.ssh_remote_ctrl_even_mini_sys(self.cli, cmd, password, self.lang)
            if is_succ:
                self.logger.info("ssh to 0 controller successful.")
                return
            # 重试的时间间隔为5秒
            time.sleep(5)


def compare_patch_version(version1, version2):
    return compare_str_version(format_patch_version(version1),
                               format_patch_version(version2))


def compare_str_version(version1, version2):
    if version1 == version2:
        return 0
    return 1 if version1 > version2 else -1


def format_patch_version(version):
    find_versions = re.findall(r"SPH(\d+)", version)
    sph_ver = find_versions[0] if find_versions else "0"
    return "SPH{}".format(sph_ver.zfill(5))

