# -*- coding: utf-8 -*-
from utils.common.fic_base import TestCase
import utils.common.log as logger
from plugins.DistributedStorage.scripts.logic.InstallOperate import InstallOperate
from utils.client.FSPAuthClient import FSPAuthClient
import utils.constant.constant as constant
from plugins.DistributedStorage.scripts.utils.config.DeviceCheck import DeviceResource
from utils.common.OpenStackNodeManager import OpenStackNodeManager
from utils.Driver.CloudDC.OpenStack.get_host_info import GetHostInfo
from platforms.project.ProjectUtils import get_project_condition_boolean


class InstallRole(TestCase):
    def __init__(self, project_id, pod_id, fs_args, condition=None, metadata=None, **kwargs):
        super(InstallRole, self).__init__(project_id, pod_id)
        self.osd_list = fs_args.get('osd_list')
        self.fsa_list = fs_args.get('fsa_list')
        self.vbs_list = fs_args.get('vbs_list')
        self.openstack_nodes = fs_args.get('all_openstack_nodes')
        self.operate = InstallOperate(self.project_id, self.pod_id, fs_args)
        self.cps_web_client = FSPAuthClient.get_cps_web_client(self.db, self.project_id, self.pod_id)
        self.cps_host_client = GetHostInfo(self.cps_web_client)
        self.condition = condition
        self.metadata = metadata
        self.more_args = kwargs

    def procedure(self):
        # 1. 配置控制节点fusionstorage-blockXXX角色
        logger.info('Start clone and config fusionstorage-blockXXX')
        controller_bmc_ip_list = OpenStackNodeManager.get_controller_bmc_ip(self.db, self.pod_id)
        osd_bmc_ip_list = [osd.get('bmc_ip') for osd in self.osd_list]
        controller_osd_bmc_list = set(controller_bmc_ip_list).intersection(set(osd_bmc_ip_list))
        controller_id_list, controller_ip_list = self.cps_host_client.get_host_info(controller_osd_bmc_list)
        if get_project_condition_boolean(self.project_id, "manageARM"):
            osd_cpu = 8
        else:
            osd_cpu = 6
        osd_memory = self.get_memory_value(self.openstack_nodes)
        logger.info('Start config and install role for node%s' % controller_ip_list)
        self.operate.config_and_deploy_role(controller_id_list, osd_cpu, osd_memory)

        # 2. 配置云服务节点fusionstorage-blockXXX角色
        cloudservice_bmc_ip_list = OpenStackNodeManager.get_compute_cloudservice_bmc_ip(self.db, self.pod_id)
        fsa_bmc_ip_list = [fsa.get('bmc_ip') for fsa in self.fsa_list]
        cloudservice_fsa_bmc_list = set(cloudservice_bmc_ip_list).intersection(set(fsa_bmc_ip_list))
        cloudservice_id_list, cloudservice_ip_list = self.cps_host_client.get_host_info(cloudservice_fsa_bmc_list)
        if len(cloudservice_bmc_ip_list) > 0:
            if get_project_condition_boolean(self.project_id, "manageARM"):
                cloudservice_cpu = 8
            else:
                cloudservice_cpu = 6
            cloudservice_memory = osd_memory
            logger.info('Start config and install role for node%s' % cloudservice_ip_list)
            self.operate.config_and_deploy_role(cloudservice_id_list, cloudservice_cpu, cloudservice_memory)

        logger.info('Checking FusionStorage-Agent rpm package')
        self.operate.check_fusionstorage_agent_rpm(self.fsa_list)

    def cleanup(self):
        vbs_bmc_ip_list = [vbs.get('bmc_ip') for vbs in self.vbs_list]
        vbs_host_id_list, vbs_host_ip_list = self.cps_host_client.get_host_info(vbs_bmc_ip_list)
        cps_client = FSPAuthClient.get_cps_rest_client(self.db, self.project_id, self.pod_id)
        logger.info("Stop fusionstorage-blockXXX role nodes%s" % str(vbs_host_ip_list))
        self.operate.stop_fusionstorage_block_template(cps_client, vbs_host_id_list)
        logger.info("Cleaning up fusionstorage-blockXXX role nodes%s" % str(vbs_host_ip_list))
        self.operate.remove_fusionstorage_block_role(cps_client, vbs_host_id_list)
        logger.info("Checking fusionstorage-blockXXX role nodes%s" % str(vbs_host_ip_list))
        self.operate.check_fusionstorage_block_on_host(cps_client, vbs_host_id_list)

    @staticmethod
    def get_memory_value(nodes, scene=None, mode=None):
        check = DeviceResource()
        # 获取主存槽位
        storage_slot_list = [unit["primary_slot"] for unit in nodes if
                             unit["bmc_role"] == constant.BMCROLE.FIRST_NODE or
                             unit["bmc_role"] == constant.BMCROLE.CONTROLLER_NODE]
        storage_slot = check.get_storage_pool_slot(storage_slot_list)

        # 获取缓存容量
        cache_capacity_slot = [unit["cache_capacity"] for unit in nodes if
                               unit["bmc_role"] == constant.BMCROLE.FIRST_NODE or
                               unit["bmc_role"] == constant.BMCROLE.CONTROLLER_NODE]
        cache_capacity = ''
        # 缓存容量一致性检查
        for capacity in cache_capacity_slot:
            if not cache_capacity:
                if not capacity:
                    # 控制节点的缓存容量为空时抛异常
                    raise Exception("The cache capacity of controller node is empty")
                cache_capacity = capacity
            else:
                if cache_capacity != capacity:
                    # 控制节点的缓存容量不一致时抛异常
                    raise Exception("The cache capacity of controller node must be same")

        # 获取主存容量
        primary_capacity_slot = [unit["primary_capacity"] for unit in nodes if
                                 unit["bmc_role"] == constant.BMCROLE.FIRST_NODE or
                                 unit["bmc_role"] == constant.BMCROLE.CONTROLLER_NODE]
        primary_capacity = ''
        # 主存容量一致性检查
        for capacity in primary_capacity_slot:
            if not primary_capacity:
                if not capacity:
                    # 控制节点的主存容量为空时抛异常
                    raise Exception("The primary capacity of controller node is empty")
                primary_capacity = capacity
            else:
                if primary_capacity != capacity:
                    # 控制节点的主存容量不一致时抛异常
                    raise Exception("The primary capacity of controller node must be same")
        memory = check.get_fsa_memory_800(storage_slot, cache_capacity, primary_capacity, condition='manageFB')
        return memory
