# -*- coding: utf-8 -*-
from plugins.ResourceCheck.common.libs.BMCCmd import BMCCmdExc
from utils.DBAdapter.DBConnector import BaseOps
from utils.common.fic_base import StepBaseInterface
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 Do_Check(TestCase):
    def __init__(self, project_id, pod_id):
        self.pod_id = pod_id
        self.project_id = project_id

    def pre_condition(self):
        pass

    def procedure(self):

        """
        检查管理节点、云服务节点是否使用了华为的ES3000 V3/V5 ssd。
       """
        try:
            self.cmd_exe = BMCCmdExc()
            self.db = BaseOps()
            bmc_info_lists = self.db.get_bmc_info_by_pod_id(self.pod_id)
            bmc_ip_list = []
            for bmc_info in bmc_info_lists:
                bmc_ip = bmc_info["bmc_ip"]
                bmc_role = bmc_info["ref_component"]
                cache_type = bmc_info["cache_type"]
                if cache_type == 'ssd_card' and 'osd' in bmc_role:
                    logger.info('Need to check BMC: %s' % bmc_ip)
                    bmc_ip_list.append(bmc_ip)

            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 = self.cmd_exe.run(bmc_ip_list, cmd)
            logger.info("Exec cmd: %s, result: %s" % (cmd, result_all))
            fail_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)
                    fail_list.append(bmc_ip)
            if fail_list:
                logger.error('These nodes is not a Huawei server: %s' % fail_list)
                raise HCCIException(113193, str(fail_list))
            # 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 = self.cmd_exe.run(bmc_ip_list, cmd)
            logger.info("Exec cmd: %s, result: %s" % (cmd, result_all))
            fail_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))
            return True, None
        except HCCIException as e1:
            raise e1
        except Exception as e2:
            raise e2

    def post_condition(self):
        pass

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


class Check(StepBaseInterface):
    def __init__(self, project_id, pod_id):
        super(Check, self).__init__(project_id, pod_id)
        self.project_id = project_id
        self.pod_id = pod_id
        self.implement = Do_Check(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)
        except Exception as e2:
            return Message(500, HCCIException(627209, str(e2)))

    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


