# -*-coding:utf-8-*-
import json
import re
import stat
import os
from configparser import ConfigParser

from utils.common import log as logger
from utils.DBAdapter.DBConnector import BaseOps
from utils.constant.path_constant import ProjectPluginsPath
from plugins.ResourceCheck.common.libs.BMCCmd import BMCCmdExc
from plugins.DistributedStorage.logic.DeployOperate import DeployOperate
from plugins.DistributedStorage.utils.common.DeployConstant import DeployConstant


class CpuOperate(object):
    JSON_PATH = r'{}/DistributedStorage/Deploy/scripts/PreCheck/common/distributed_storage_node_cpu_arch.json' \
        .format(ProjectPluginsPath.project_plugins_path())

    @classmethod
    def update_json_file(cls, json_path, stream):
        """不存在创建json文件，存在则清空内容后写入stream"""
        flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
        modes = stat.S_IWUSR | stat.S_IRUSR | stat.S_IXUSR | stat.S_IRGRP | stat.S_IXGRP
        with os.fdopen(os.open(json_path, flags, modes), 'w') as f:
            json.dump(stream, f, indent=2, ensure_ascii=False)

    @classmethod
    def get_system_arch(cls, bmc_ip_list):
        """
        minios中获取分离部署存储节点CPU架构存入json文件
        :return:
        """
        cmd = "uname -p"
        cmd_exe = BMCCmdExc()
        bmc_ip_list = list(set(bmc_ip_list))
        result_all = cmd_exe.run(bmc_ip_list, cmd)
        logger.info("Exec cmd: %s, result: %s" % (cmd, result_all))
        for bmc_ip in bmc_ip_list:
            result = result_all[bmc_ip]['stdout']
            ret_arch_list = re.findall('x86_64|aarch64', result)
            if len(ret_arch_list) == 1:
                ret_arch = ret_arch_list[0]
            else:
                err_msg = "Failed query cpu arch, cmd result:%s find:%s" % (result, ret_arch_list)
                logger.error(err_msg)
                raise Exception(err_msg)
            if ret_arch == 'x86_64':
                serv_cpu_arch = 'X86'
            elif ret_arch == 'aarch64':
                serv_cpu_arch = 'ARM'
                result_all.get(bmc_ip)["is_1880"] = cls.get_1880_raid_node([bmc_ip]).get(bmc_ip).get('is_1880')
            else:
                serv_cpu_arch = 'Unkown'
                err_msg = "Failed get processor type, cmd result:%s find:%s" % (result, serv_cpu_arch)
                logger.error(err_msg)
                raise Exception(err_msg)
            logger.info("Processor type:%s" % serv_cpu_arch)
            result_all[bmc_ip]['stdout'] = serv_cpu_arch
        cls.update_json_file(cls.JSON_PATH, result_all)
        return result_all

    @classmethod
    def get_1880_raid_node(cls, bmc_ip_list):
        cmd = "lspci |grep -v grep|grep RAID.*3758"
        cmd_exe = BMCCmdExc()
        bmc_ip_list = list(set(bmc_ip_list))
        result_all = cmd_exe.run(bmc_ip_list, cmd)
        logger.info("Exec cmd: %s, result: %s" % (cmd, result_all))
        for bmc_ip in bmc_ip_list:
            is_1880 = False
            result = result_all.get(bmc_ip).get('stdout')
            if re.search("RAID.*3758", result):
                is_1880 = True
            result_all.get(bmc_ip)['is_1880'] = is_1880
        return result_all

    @classmethod
    def get_3152_raid_node(cls, bmc_ip_list: list):
        cmd_exe = BMCCmdExc()
        cmd = DeployConstant.DRIVER_TYPE_CONDITION.get("3152").get("cmd")
        result_all = cmd_exe.run(bmc_ip_list, cmd)
        logger.info("Exec cmd: %s, result: %s" % (cmd, result_all))
        for bmc_ip in bmc_ip_list:
            result = result_all.get(bmc_ip).get('stdout')
            pattern = DeployConstant.DRIVER_TYPE_CONDITION.get("3152").get("pattern")
            result_all.get(bmc_ip)['is_3152'] = True if re.search(pattern, result) else False
        return result_all


class PreCheckPublicOperate:
    def __init__(self, project_id, pod_id, *args, **kwargs):
        self.project_id = project_id
        self.pod_id = pod_id
        self.args = args
        self.kwargs = kwargs
        self.database = BaseOps()

    @classmethod
    def get_plugins_version(cls):
        plugin_path = ProjectPluginsPath.project_plugins_path()
        cfg_path = r"{}/DistributedStorage/utils/common/config.ini".format(plugin_path)
        cfg = ConfigParser()
        cfg.read(cfg_path)
        plugins_version = cfg.get("plugins_version", "plugins_version")
        logger.info("plugins_version: {}".format(plugins_version))
        return plugins_version

    @classmethod
    def get_product_version(cls, float_ip, portal_pwd):
        opr = DeployOperate(float_ip=float_ip)
        opr.login(DeployConstant.DM_LOGIN_USER, portal_pwd)
        try:
            _, rsp_data = opr.get_product()
        finally:
            opr.logout()
        product_version = rsp_data.get("version")
        logger.info('Pacific Version: {}'.format(product_version))
        return product_version

    def get_bmc_info(self, need_rep=False):
        ret = []
        all_bmc_info = self.database.get_install_os_list_info(self.pod_id)
        if need_rep:
            ret.extend(self.database.get_install_os_list_info(self.pod_id, component="rep"))
        all_bmc_ip = set()
        for node_info in all_bmc_info:
            if node_info.get("bmc_ip") not in all_bmc_ip:
                ret.append(node_info)
                all_bmc_ip.add(node_info.get("bmc_ip"))
        return ret
