#  coding=UTF-8
#  Copyright (c) Huawei Technologies Co., Ltd. 2019-2019. All rights reserved.

from cbb.frame.cli import cliUtil
from cbb.frame.base import baseUtil
from java.lang import Exception as JException
import traceback
from resource.resource import MESSAGES_DICT
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 service.func_utils import check_recs_by_rest
from service.func_utils import check_recs_by_tlv
from checkitems.evaluate_pre_check import link_pre_check

ALARM_ID = ["0xF00A000C", "0xF000A0112"]
# 根据检查项获取配置字典值
PATCH_EVALU = 'PATCH_EVALU'

DEVICE_TYPE_V5_LIST = [
    "5600 V5",
    "5600F V5",
    "5800 V5",
    "5800F V5",
    "6800 V5",
    "6800F V5",
    "18500 V5",
    "18500F V5",
    "18800 V5",
    "18800F V5",
]
VERSION_V5_LIST = [
    "V500R007C00",
    "V500R007C00SPC100",
    "V500R007C10",
    "V500R007C20",
    "V500R007C30SPC100",
]
DEVICE_TYPE_DORADO_LIST = ["Dorado6000 V3", "Dorado18000 V3"]
VERSION_DORADO_LIST = [
    "V300R001C21",
    "V300R001C21SPC100",
    "V300R001C30",
    "V300R001C30SPC100",
    "V300R002C00",
    "V300R002C00SPC100",
    "V300R002C10SPC100",
]


def execute(context):
    """
    磁盘单链路检查
    :param context:
    :return:
    """
    flag, err_msg, cli_ret = disk_link_pre_check(context)
    if flag:
        return flag, err_msg, cli_ret
    lang = contextUtil.getLang(context)
    log = common.getLogger(contextUtil.getLogger(context), __file__)
    tlv = contextUtil.getTlv(context)
    cli_ret_value = ""
    err_msgs = list()
    flag = True
    try:
        checkItem = "CHECK_DISK_LINKSTATUS"
        item_dict = tlvData.UPD_CHECK_RESULT[checkItem]
        cli_ret_value = get_cli_ret(context, log)
        log.logExecCmd(checkItem)
        try:
            # 根据检查项获取配置字典值 新版本适用
            recs = tlvUtil.get_upgrade_records(tlv, checkItem)
            log.logInfo("records={}".format(recs))
            flag = check_recs_by_rest(item_dict, recs, err_msgs, lang)
        except (JException, Exception) as e:
            log.logException(e)
            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 = "ld checksinglelink"
                flag = check_recs_by_tlv(
                    context, cmd, err_msgs, log, item_dict
                )
        return flag, "\n".join(err_msgs), cli_ret_value
    except Exception as exception:
        log.logException(exception)
        return (
            False,
            baseUtil.getPyResource(
                lang, "query.result.abnormal", resource=MESSAGES_DICT
            ),
            cli_ret_value,
        )


def disk_link_pre_check(context):
    """
    进行版本范围，空闲内存及是否单控检查，如果有一个命中则继续检查
    :param context:
    :return:
    """
    cli_ret_list = list()
    flag, cli_ret = is_risk_version(context)
    cli_ret_list.append(cli_ret)
    if flag:
        return False, "", cli_ret
    # 只有补丁评估会走检查空闲内存和单控的逻辑
    if context.get('dev').getMatchType() != PATCH_EVALU:
        return True, "", "\n".join(cli_ret_list)
    flag, err_msg, cli_ret = link_pre_check(context)
    cli_ret_list.append(cli_ret)
    if not flag:
        return False, err_msg, cli_ret

    return True, "", "\n".join(cli_ret_list)


def get_cli_ret(context, log):
    # 获取cli回显，不管回显是啥都将其返回到原始信息
    cli = contextUtil.getCliCommon(context)
    lang = contextUtil.getLang(context)
    log.logInfo("alarmIds={}".format(ALARM_ID))
    cli_rets = list()
    for alarmId in ALARM_ID:
        cmd = (
            "show alarm |filterRow column=ID predict=equal_to value=%s"
            % alarmId
        )
        try:
            cli_rets.append(cliUtil.excuteCmdInCliMode(cli, cmd, True, lang)[1])
        except (JException, Exception) as e:
            log.logException(e)
    return "\n".join(cli_rets)


def is_risk_version(context):
    devType = str(context.get("dev").getDeviceType())
    productVersion = str(context.get("dev").getProductVersion())
    if "dorado" in devType.lower():
        flag = (
            devType in DEVICE_TYPE_DORADO_LIST
            and productVersion in VERSION_DORADO_LIST
        )
    else:
        flag = (
            devType in DEVICE_TYPE_V5_LIST
            and productVersion in VERSION_V5_LIST
        )

    return (
        flag,
        "dev_type : {}, product_version:{}".format(devType, productVersion),
    )
