# -*- coding: utf-8 -*-

import utils.common.log as logger
from plugins.ResourceCheck.common.libs import network_libs
from utils.DBAdapter.DBConnector import BaseOps
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


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

    def pre_condition(self):
        return Message(200)

    def nic_check(self, node_info, plane_type):
        """检查管理面存储面 填的网口信息是否正确
        单网卡  应该是 管理面  5.1 存储 5.2
        双网卡  应该是 管理面 5.1,1.1， 存储面 5.2,1.2
        """
        if plane_type == "management_plane":
            other_type = "storage_plane"
        else:
            other_type = "management_plane"
        nic_list_m = node_info[plane_type].split(",")
        nic_list_s = node_info[other_type].split(",")
        if len(nic_list_m) == 2:
            if nic_list_m[0].split(".")[0] == nic_list_m[1].split(".")[0]:
                return False
            set_m = set([temp_nic.split(".")[0] for temp_nic in nic_list_m])
            set_s = set([temp_nic.split(".")[0] for temp_nic in nic_list_s])
            if len(set_m & set_s) != 2:
                return False
            return True
        elif len(nic_list_m) == 1:
            if nic_list_m[0].split(".")[0] != nic_list_s[0].split(".")[0]:
                return False
            return True
        return False

    def procedure(self):

        """
        检查槽位
        """
        try:
            self.db = BaseOps()
            bmc_info_lists = self.db.get_install_os_list_info(self.pod_id)
            pci_obj = network_libs.NicPciCls(bmc_info_lists)
            for bmc_info in bmc_info_lists:
                logger.info("bmc_ip:%s Nic slot map check" % bmc_info['bmc_ip'])
                manage_nic_list = bmc_info['management_plane'].replace(' ', '').split(',')
                storage_nic_list = bmc_info['storage_plane'].replace(' ', '').split(',')
                nic_list = manage_nic_list + storage_nic_list
                for slot in nic_list:
                    nic = pci_obj.get_nic_name_by_slot(bmc_info['bmc_ip'], slot, ignore_err=True)
                    if nic:
                        logger.info('slot: %s, nic %s' % (slot, nic))
                    else:
                        logger.error("Nic slot map is wrong.Bmc ip is %s,nic slot map is %s"
                                     % (bmc_info['bmc_ip'], nic_list))
                        raise HCCIException("625300", bmc_info['bmc_ip'], slot)
            logger.info("Nic slot map check success")
            return True, None
        except HCCIException as e1:
            raise e1
        except Exception as e2:
            raise e2

    def post_condition(self):
        return Message(200)

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


class PreConfig(StepBaseInterface):
    def __init__(self, project_id, pod_id):
        super(PreConfig, self).__init__(project_id, pod_id)
        self.project_id = project_id
        self.pod_id = pod_id
        self.implement = Do_Pre_Config(project_id, pod_id)

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

    def execute(self, project_id, pod_id):
        try:
            self.implement.procedure()
            return Message(200)
        except HCCIException as e1:
            logger.error("Separate storage node install os pre_config fail, fail detail is %s" % str(e1))
            return Message(500, e1)
        except Exception as e2:
            logger.error("Separate storage node install os pre_config fail, fail detail is %s" % str(e2))
            return Message(500, HCCIException('625301', 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:
        """
        return Message(200)
