# -*- coding: utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
import utils.common.log as logger
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
from utils.common.exception import HCCIException
from plugins.ResourceCheck.common.libs.BMCCmd import BMCCmdExc


class CheckSSDCardImpl(TestCase):
    def __init__(self, project_id, pod_id):
        self.pod_id = pod_id
        self.project_id = project_id
        self.cmd_exe = BMCCmdExc()
        self.db = BaseOps()

    def procedure(self):
        """检查管理节点、云服务节点是否使用了华为的ES3000 V3/V5 ssd。"""
        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))


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 = CheckSSDCardImpl(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()
        except HCCIException as e1:
            return Message(500, e1)
        except Exception as e2:
            return Message(500, HCCIException(627209, str(e2)))
        return Message(200)

    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


