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

from com.huawei.ism.tool.obase.exception import ToolException

from cbb.frame.base import baseUtil
from cbb.frame.cli import cliUtil
from cbb.frame.context import contextUtil

from resource.resource import MESSAGES_DICT


def execute(data_dict):
    """ 检查方法：
    步骤1 以admin用户登录设备；
    步骤2 执行命令：show service ndmp，查询ndmp服务是否开启；
    步骤3 执行命令：show vstore |filterColumn include columnList=ID，获取ID字段的值；
    步骤4 执行命令：change vstore view id=ID（步骤3中的ID），进入租户视图；
    步骤5 执行命令：show service ndmp，获取当前租户查询ndmp服务是否开启；
    步骤6 执行命令：exit，退出租户模式；
    步骤7 遍历步骤3中查出的所有租户ID执行步骤4-6。
    检查标准：1.步骤2或者步骤5中存在Is Enabled字段为Yes，检查不通过；否则检查通过；
    :param data_dict: 上下文信息
    :return: 检查结果
    """
    # 执行升级前检查
    return NdmpServiceEnable(data_dict).execute()


class NdmpServiceEnable:
    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.enable_ndmp_tenant_id_list = []
        self.failed_tenant_id_list = []
        self.origin_info = []
        self.err_msg_list = []

    def execute(self):
        try:
            self.logger.info("dev_type:{} ".format(self.dev_type))
            if baseUtil.is_computing_dev(self.dev_type):
                return True, "", "dev_type:{}".format(self.dev_type)

            cli_ret = self.__query_ndmp_service()
            if cli_ret[0] is not True:
                if not NdmpServiceEnable.__support_ndmp_service(cli_ret[1]) \
                        or cli_ret[0] == cliUtil.RESULT_NOSUPPORT:
                    return True, "", cli_ret[1]
                error_key = "ndmp.service.get.ndmp.service.error"
                self.__append_error_info(error_key)
                return self.__merge_check_result()

            if NdmpServiceEnable.__ndmp_service_enable(cli_ret[1]):
                self.logger.info("The ndmp status of the system view "
                                 "is enable.")
                error_key = "ndmp.service.enable.sys"
                self.__append_error_info(error_key)

            check_flag = self.__check_ndmp_in_tenant()
            if not check_flag:
                return self.__merge_check_result()

            self.logger.info("Enable ndmp service tenant id:{}".format(
                self.enable_ndmp_tenant_id_list))
            self.__append_tenant_check_result()
            return self.__merge_check_result()
        except ToolException as e:
            self.logger.error("Excute ndmp service check exception:"
                              "{}".format(str(e)))
            error_key = "ndmp.service.check.error"
            self.__append_error_info(error_key)
            return self.__merge_check_result()

    def __append_tenant_check_result(self):
        if self.enable_ndmp_tenant_id_list:
            error_key = "ndmp.service.enable.tenant"
            param = ", ".join(self.enable_ndmp_tenant_id_list)
            self.__append_error_info(error_key, param)

        if self.failed_tenant_id_list:
            error_key = "ndmp.service.get.info.error.tenant"
            param = ", ".join(self.failed_tenant_id_list)
            self.__append_error_info(error_key, param)

    def __merge_check_result(self):
        if self.err_msg_list:
            error_key = "ndmp.service.sugg"
            self.__append_error_info(error_key)
            return False, "\n".join(self.err_msg_list), "\n"\
                .join(self.origin_info)

        return True, "", "\n".join(self.origin_info)

    def __append_error_info(self, error_key, param=""):
        err_msg = baseUtil.getPyResource(self.lang, error_key, param,
                                         resource=MESSAGES_DICT)
        self.err_msg_list.append(err_msg)

    @staticmethod
    def __support_ndmp_service(cli_ret):
        if "^" in cli_ret:
            return False
        return True

    @staticmethod
    def __ndmp_service_enable(cli_ret):
        cli_ret_lines_list = cliUtil.getVerticalCliRet(cli_ret)
        for cli_ret_line in cli_ret_lines_list:
            enabled = cli_ret_line.get("Is Enabled").strip()
            if enabled.lower() == 'yes':
                return True
        return False

    def __check_ndmp_in_tenant(self):
        flag, vstore_view_id_list = self.__get_vstore_view_ids()
        if flag is not True:
            self.logger.info("Get vstore id failed.")
            return False
        cmd = "show service ndmp"
        self.logger.info("The vstore id list:{}".format(vstore_view_id_list))
        for vstore_id in vstore_view_id_list:
            try:
                cli_ret = cliUtil.excute_cmd_in_vstore_model(
                    self.cli, cmd, self.lang, vstore_id)
                self.origin_info.append(cli_ret[1])
                if NdmpServiceEnable.__ndmp_service_enable(cli_ret[1]):
                    self.enable_ndmp_tenant_id_list.append(vstore_id)
            except ToolException:
                self.failed_tenant_id_list.append(vstore_id)
                cliUtil.reConnectionCli(self.cli, self.logger)
        return True

    def __query_vstore_view_id(self):
        cmd = "show vstore |filterColumn include columnList=ID"
        cli_ret = cliUtil.excuteCmdInCliMode(self.cli, cmd, True, self.lang)
        return cli_ret

    def __get_vstore_view_ids(self):
        vstore_view_id_list = []
        cli_ret = self.__query_vstore_view_id()
        if cli_ret[0] not in [True, cliUtil.RESULT_NOSUPPORT]:
            error_key = "ndmp.service.get.vstore.id.error"
            self.__append_error_info(error_key)
            return False, []

        cli_ret_list = cliUtil.getHorizontalCliRet(cli_ret[1])
        for line in cli_ret_list:
            vstore_id = line.get("ID", "")
            if vstore_id:
                vstore_view_id_list.append(vstore_id)
        return True, vstore_view_id_list

    def __query_ndmp_service(self):
        cmd = "show service ndmp"
        cli_ret = cliUtil.excuteCmdInCliMode(self.cli, cmd, True, self.lang)
        self.origin_info.append(cli_ret[1])
        return cli_ret
