# -*- coding: utf-8 -*-
from plugins.ResourceCheck.common.libs import common_libs
from utils.common.fic_base import StepBaseInterface
from plugins.ResourceCheck.common.libs.BMCCmd import BMCCmdExc
from utils.common.fic_base import TestCase
from utils.common.message import Message
import utils.common.log as logger
from utils.common.exception import HCCIException


class DoCheckTenantFBHeterogeneousSSD(TestCase):
    def pre_condition(self):
        pass

    def procedure(self):

        """
        分离部署,检查存储节点SSD硬盘数量和类型:1. 资源池内的SSD卡/SSD盘数量和类型必须一致。2. 资源池内缓存介质类型一致。
        """
        try:
            common_libs.check_flag()
            bmc_list = self.db.get_install_os_list_info(self.pod_id)
            if not bmc_list:
                return True, None

            cmd_exe = BMCCmdExc()
            bmc_ip_list = list()
            for bmc in bmc_list:
                bmc_ip = bmc.get("bmc_ip")
                cache_type = bmc.get("cache_type")
                if cache_type == 'ssd_card':
                    logger.info('Need to check BMC: %s' % bmc_ip)
                    bmc_ip_list.append(bmc_ip)
            if not bmc_ip_list:
                logger.info('No bmc found')
                return True, None

            logger.info('Start to exec cmd to bmc, bmc list：%s' % bmc_ip_list)
            cmd = "ipmitool fru print 0 | grep Huawei | wc -l"
            result_all = cmd_exe.run(bmc_ip_list, cmd)
            logger.info("Exec cmd: %s, result: %s" % (cmd, result_all))
            not_huawei_list = list()
            logger.info('Start to check nvme ssd')
            for bmc_ip in bmc_ip_list:
                result = result_all[bmc_ip]['stdout']
                if int(result) == 0:
                    logger.info('node %s is not a Huawei server' % bmc_ip)
                    not_huawei_list.append(bmc_ip)
            if not_huawei_list:
                logger.error('These nodes is not a Huawei server: %s, skip.' % not_huawei_list)
                return True, None

            # 19e5:0123/19e5:3714：ES3000 V3/V5
            # 144d:a822/144d:a824：Samsung PM1725b/PM1735
            # 8086:0a54：Intel P4610
            # 1e81:1203/1cc4:1203：白牌A28
            cmd = "lspci -n | grep -E '19e5:0123|19e5:3714|144d:a822|144d:a824|8086:0a54|1e81:1203|1cc4:1203' | wc -l"
            result_all = cmd_exe.run(bmc_ip_list, cmd)
            logger.info("Exec cmd: %s, result: %s" % (cmd, result_all))
            fail_list = list()
            logger.info('start to check nvme ssd')
            for bmc_ip in bmc_ip_list:
                result = result_all[bmc_ip]['stdout']
                if int(result) > 0:
                    logger.info('node %s has %s nvme ssd' % (bmc_ip, result))
                else:
                    logger.info('node %s has no nvme ssd' % bmc_ip)
                    fail_list.append(bmc_ip)
            if fail_list:
                logger.error('These nodes have no nvme ssd %s' % fail_list)
                raise HCCIException(113191, str(fail_list))

            logger.info('start to check nvme ssd count')
            ssd_count = None
            first_bmc = None
            for bmc_ip in bmc_ip_list:
                result = result_all[bmc_ip]['stdout']
                if ssd_count is None:
                    ssd_count = int(result)
                    first_bmc = bmc_ip
                if int(result) != ssd_count:
                    logger.error("bmc[%s] ssd card number(%s) is difference with first bmc[%s] ssd card number(%s)"
                                 % (bmc_ip, int(result), first_bmc, ssd_count))
                    raise HCCIException(113192, bmc_ip, first_bmc)

            return True, None
        except HCCIException as e1:
            raise e1
        except Exception as e2:
            raise e2

    def post_condition(self):
        pass

    def failure(self):
        super(DoCheckTenantFBHeterogeneousSSD, self).failure()
        # 环境恢复脚本


class CheckTenantFBHeterogeneousSSD(StepBaseInterface):
    def __init__(self, project_id, pod_id):
        self.project_id = project_id
        self.pod_id = pod_id
        self.implement = DoCheckTenantFBHeterogeneousSSD(project_id, pod_id)

    def pre_check(self, project_id, pod_id):
        """
        插件内部接口：执行安装前的资源预检查，该接口由execute接口调用，工具框架不会直接调用此接口。
        :param project_id:
        :param pod_id:
        :return:
        """
        pass

    def execute(self, project_id, pod_id):
        try:
            self.implement.procedure()
            return Message(200)
        except HCCIException as e1:
            return Message(500,e1)

    def rollback(self, project_id, pod_id):
        """
        标准调用接口：执行回滚
        :param project_id:
        :param pod_id:
        :return:Message类对象
        """
        return Message(200)

    def retry(self, project_id, pod_id):
        """
        标准调用接口：重试
        :return: Message类对象
        """
        return self.execute(project_id, pod_id)

    def check(self, project_id, pod_id):
        """
        标准调用接口：重试
        :param project_id:
        :param pod_id:
        :return:
        """
        pass

