# -*- coding: UTF-8 -*-

from common.baseFactory import *
from common import resourceParse 
from common.baseFactory import log
from frame.rest.restUtil import Tlv2Rest
from frame.rest import restData

from cbb.frame.rest.restUtil import Tlv2Rest as cbb_tlv2rest
from cbb.frame.util.common import is_cold_patch
from service.patch_multi_service import PatchMultiPackagesManager

# 错误码为reinstall时，当前补丁版本为下列版本时，需要先安全预处理补丁
PRE_PROCESS_PATCH_VER = ["V300R002C20SPH070", "V300R002C20SPH075"]
# 错误码为reinstall时，当前补丁版本为下列版本时，需要先安全预处理补丁
PRE_UNINSTAL_PATCH_VER = ["V300R002C20SPH071", "V300R002C20SPH073"]

ERR_CODE_2_ERR_DESC = {
    "true": "HotPatchCheck.pass",
    "pkgerror": "HotPatchCheck.notpass.pkgerror",
    "versionerror": "HotPatchCheck.notpass.versionerror",
    "memoryerror": "HotPatchCheck.notpass.memoryerror",
    "sysdiskerror": "HotPatchCheck.notpass.sysdiskerror",
    "sysbusy": "HotPatchCheck.notpass.sysbusy",
    "hotpatcherror": "HotPatchCheck.notpass.hotpatcherror",
    "relationshiperror": "HotPatchCheck.notpass.relationshiperror",
    "TimeOut": "HotPatchCheck.timeout",
}


def execute(data_dict):
    # 执行升级前检查
    try:
        return pre__check(data_dict)
    finally:
        delete_pkg(data_dict)


def delete_pkg(data_dict):
    """
    删除内存补丁
    :param dataDict:
    :return:
    """
    if is_cold_patch(data_dict.get("pkgVersion")):
        return

    hot_patch_path = data_dict['packagePath']
    manager = PatchMultiPackagesManager(data_dict, hot_patch_path)
    if manager.is_multi_patch_package():
        return

    cbb_tlv2rest.delete_packages(data_dict)
    return


def dispose_recs(recs, data_dict):
    """
    查询升级检查项，并更新界面
    :param recs:检查项回显
    :param data_dict:上下文信息
    :return:（boolean, err_msg, None)
            True:检查通过；False：检查不通过；
            err_msg:检查项提示；
    """
    lang = data_dict['lang']
    resource = resourceParse.execute(lang)
    rec_num = recs.size()
    
    check_err_msg = ''
    item_state = True
    for index in range(0, rec_num):
        rec = recs.get(index)
        node_id = Tlv2Rest.getRecordValue(
            rec, restData.Upgrade.RecordParam.RECORD_NODE_ID)
        result = Tlv2Rest.getRecordValue(
            rec, restData.Upgrade.RecordParam.RECORD_RESULT)
        log.info(data_dict, "PatchCheck result:" + result)
        error_key, item_state = get_check_err_key(data_dict,
                                                  item_state, result)
        check_err_msg += node_id + '--' + resource.get(error_key) + '\n'

    if not check_err_msg:
        item_state = False
        check_err_msg = resource.get("HotPatchCheck.error")
    return item_state, check_err_msg, None


def pre__check(data_dict):
    recs = executeCheck(data_dict, "upg hotpachcheck", 2)
    return dispose_recs(recs, data_dict)


def get_check_err_key(data_dict, item_state, result):
    if result != "true":
        item_state = False

    error_key = ERR_CODE_2_ERR_DESC.get(result, "")
    if not error_key:
        error_key = get_reinstal_patcherror_key(data_dict, result)
    return error_key, item_state


def get_reinstal_patcherror_key(data_dict, result):
    dev = data_dict.get("dev")
    cur_patch_ver = dev.getHotPatchVersion()
    pkg_patch_ver = data_dict.get("pkgVersion")
    log.info(data_dict, "[PatchCheck]current patch ver:{}, package version:{}"
             .format(cur_patch_ver, pkg_patch_ver))
    if result == "reinstall":
        if cur_patch_ver in PRE_PROCESS_PATCH_VER:
            return "HotPatchCheck.notpass.reinstall.preprocess"
        if cur_patch_ver in PRE_UNINSTAL_PATCH_VER:
            return "HotPatchCheck.notpass.hotpatcherror.pre.uninstall"
        return "HotPatchCheck.notpass.reinstall"

    return "HotPatchCheck.error"
