# -*- coding: utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
import utils.common.log as logger
from utils.common.exception import HCCIException
from utils.common.fic_base import StepBaseInterface
from utils.common.fic_base import TestCase
from utils.common.message import Message
from utils.common.error.hcci_error_code import get_code_msg
from plugins.DistributedStorage.logic.deploy_operate import RedfishOperate


class CheckIOMMUInf(StepBaseInterface):
    def __init__(self, project_id, pod_id):
        super().__init__(project_id, pod_id)
        self.project_id = project_id
        self.pod_id = pod_id

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

    def execute(self, project_id, pod_id):
        try:
            DoCheckIOMMU(project_id, pod_id).procedure()
        except HCCIException as e1:
            logger.error('MMU check Error:{}'.format(e1))
            return Message(500, e1)
        except Exception as e2:
            logger.error('MMU check Error:{}'.format(e2))
            return Message(500, HCCIException(113999, 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:
        """
        return Message()


class DoCheckIOMMU(TestCase):
    def __init__(self, project_id, pod_id):
        super().__init__(project_id, pod_id)
        self.project_id = project_id
        self.pod_id = pod_id

    @classmethod
    def get_mmu_status(cls, bmc_ip, password, user_name):
        redfish_client = RedfishOperate(bmc_ip, user_name, password)
        cpu_arch = redfish_client.get_system_arch()
        iommu_status = redfish_client.get_iommu()
        return cpu_arch, iommu_status

    def procedure(self):
        """
        检查分离部署ARM节点是否开启IOMMU
        SPDK要求关闭IOMMU，检查IOMMU是否已经关闭
        """
        node_info = self.db.get_install_os_list_info(self.pod_id) + self.db.get_install_os_list_info(self.pod_id, 'rep')
        if not node_info:
            logger.info('No storage node exists, pass')
            return
        error_list = []
        for node in node_info:
            bmc_ip = node.get("bmc_ip")
            user_name = node.get("bmc_name")
            password = node.get("bmc_passwd")
            try:
                cpu_arch, iommu_status = self.get_mmu_status(bmc_ip, password, user_name)
            except HCCIException as e:
                err_msg = get_code_msg(627618) % bmc_ip
                logger.error('Error:{}, details:{}'.format(err_msg, e))
                continue
            if cpu_arch != 'ARM':
                continue
            logger.info("node %s iommu status is %s." % (bmc_ip, iommu_status))
            if iommu_status == 'Enabled':
                error_list.append(bmc_ip)
        if error_list:
            logger.error('node: %s not disabled iommu' % error_list)
            raise HCCIException(627600, error_list)
