# -*- coding: utf-8 -*-
import re

import utils.common.log as logger
from utils.business.project_condition_utils import get_project_condition_boolean
from plugins.ResourceCheck.common.libs.BMCCmd import BMCCmdExc
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 DoCheckNic(TestCase):
    def pre_condition(self):
        return Message(200)

    def check_nic_info(self, bmc_ip_result, nic_num, nic_speed, connect_check=True):
        if bmc_ip_result["result"] == '1':
            return False
        if nic_num == 0:
            return True
        try:
            nic_num = float(nic_num)
            nic_speed = float(nic_speed)
            nic_num_yes = 0
            ret_lst = bmc_ip_result["stdout"].split("\n")
            if connect_check:
                pattern = re.compile(r'.*? (\d+)Mb/s')
                for nic_info in ret_lst:
                    if "yes" in nic_info:
                        m = pattern.match(nic_info)
                        nic_speed_yes = int(m.group(1))
                        if nic_speed_yes >= nic_speed:
                            nic_num_yes += 1
                            if nic_num_yes == nic_num:
                                return True
            else:
                for nic_info in ret_lst:
                    if "Speed" in nic_info:
                        nic_num_yes += 1
                        if nic_num_yes == nic_num:
                            return True

            if nic_num_yes < nic_num:
                return False
        except Exception as e:
            raise e
    def procedure(self):
        try:
            self.cmd_exe = BMCCmdExc()
            self.db = BaseOps()
            bmc_info_lists = self.db.get_install_os_list_info(self.pod_id)
            nic_speed_10ge = 10*1000
            nic_speed_ge = 1000
            bmc_ip_list = [bmc_info["bmc_ip"] for bmc_info in bmc_info_lists]
            cmd = r"""for eth in `ip addr | grep '^[0-9]' |awk -F':' '{print $2}'|grep -v 'lo'`; do echo -n "$eth," && 
                        ethtool $eth 2>/dev/null|grep -E "Speed: |Link detected:"|tr -d '\t'|tr '\n' ',' ; echo ""; done"""
            result = self.cmd_exe.run(bmc_ip_list, cmd)
            logger.info("Exec cmd: %s, result: %s" % (cmd, result))
            for bmc_info in bmc_info_lists:
                bmc_ip = bmc_info['bmc_ip']
                logger.info("bmc_ip:%s Nic check" % bmc_ip)
                mgmt_plane_set = set(bmc_info.get('management_plane').split(','))
                storage_plane_set = set(bmc_info.get('storage_plane').split(','))
                if mgmt_plane_set.difference(storage_plane_set):
                    nic_num_10ge = 2
                    nic_num_ge = 2
                else:
                    nic_num_10ge = 2
                    nic_num_ge = 0

                if get_project_condition_boolean(
                        self.project_id, "(CSHAStorage_TFB|CSDRStorage_TFB)&!DRStorage_TFB_Sep"):
                    nic_num_10ge = nic_num_10ge + 2

                check_result = \
                    self.check_nic_info(result[bmc_ip], nic_num_10ge + nic_num_ge,
                                        nic_speed_10ge, True)
                check_result = check_result or (
                        self.check_nic_info(result[bmc_ip], nic_num_10ge, nic_speed_10ge, True) and
                        self.check_nic_info(result[bmc_ip], nic_num_ge, nic_speed_ge, True))

                if not check_result:
                    logger.error("Nic check faild!")
                    raise HCCIException("625303", bmc_info['bmc_ip'], nic_num_10ge + nic_num_ge)
                logger.info("Nic 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(DoCheckNic, self).failure()
        # 环境恢复脚本


class CheckNic(StepBaseInterface):
    def __init__(self, project_id, pod_id):
        super(CheckNic, self).__init__(project_id, pod_id)
        self.project_id = project_id
        self.pod_id = pod_id
        self.implement = DoCheckNic(project_id, pod_id)

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

    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('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:Message类对象
        """
        return Message(200)
