# -*- coding: utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
import utils.common.log as logger
from utils.common.fic_base import TestCase
from utils.client.FSPAuthClient import FSPAuthClient
from utils.Driver.CloudDC.OpenStack.get_host_info import GetHostInfo
from plugins.ManageOne.scripts.utils.get_solution import get_solution
from plugins.DistributedStorage.logic.install_operate import InstallOperate
from plugins.DistributedStorage.utils.config.device_check import DeviceResource
from plugins.DistributedStorage.utils.common.general_query import GeneralQuery


class InstallRole(TestCase):
    def __init__(self, project_id, pod_id, fs_args, **kwargs):
        super(InstallRole, self).__init__(project_id, pod_id)
        self.fs_args = fs_args

        self.vbs_list = fs_args.get('vbs_list')
        self.fsa_list = fs_args.get('fsa_list')
        self.vbs_osd_bmc_ip_list = fs_args.get('vbs_osd_bmc_ip_list')
        self.osd_cpu = fs_args.get('osd_cpu')
        self.osd_memory = fs_args.get('osd_memory')
        self.vbs_cpu = fs_args.get('vbs_cpu')
        self.vbs_memory = fs_args.get('vbs_memory')
        self.vbs_bmc_ip_list = fs_args.get('vbs_bmc_ip_list')
        self.more_args = kwargs
        self.progress_deploy = get_solution()
        self.operate = InstallOperate(self.project_id, self.pod_id,
                                      self.fs_args)
        self.fsp_client = FSPAuthClient()
        self.cps_web_client = self.fsp_client.get_cps_web_client(
            self.db, self.project_id, self.pod_id)
        self.cps_host_client = GetHostInfo(self.cps_web_client)
        self.cps_rest_client = self.fsp_client.get_cps_rest_client(
            self.db, self.project_id, self.pod_id)
        self.check = DeviceResource()

    def procedure(self):
        logger.info('Start clone and config fusionstorage-blockXXX')
        # 1. 配置同时是osd节点和vbs节点的fusionstorage-blockXXX角色
        compute_storage_id_list = self.config_vbs_osd_node_role()
        # 2. 配置纯vbs节点的fusionstorage-blockXXX角色
        compute_id_list = self.config_vbs_node_role()
        if not compute_storage_id_list and not compute_id_list:
            err_msg = "The node list is empty. There is no node to install role"
            logger.error(err_msg)

        # 3. 检查vbs节点fusionstorage-blockXXX角色配置情况
        if self.vbs_bmc_ip_list or self.vbs_osd_bmc_ip_list:
            self.operate.check_vbs_node_fusionstorage_agent_rpm(self.vbs_list)

    def config_vbs_node_role(self):
        compute_id_list = list()
        if self.vbs_bmc_ip_list:
            compute_id_list, compute_ip_list = \
                self.cps_host_client.get_host_info(self.vbs_bmc_ip_list)

            # 已经安装过的节点，重启角色，兼容IPSAN等场景提前部署角色，然后跳过后续安装
            if self.operate.check_fusionstorage_block_before_install_role(
                    self.cps_rest_client, compute_id_list):
                logger.info('Restart config and install role for compute'
                            ' nodes[%s]' % compute_ip_list)
                self.operate.restart_fusionstorage_block_template(
                    self.cps_rest_client, compute_id_list)
            else:
                for sub_computer_id_list, cpu in self.divide_host_by_group(compute_id_list):
                    logger.info('Start config and install role for compute '
                                'nodes[%s], cpu[%s], memory[%s]' %
                                (sub_computer_id_list, cpu,
                                 self.vbs_memory))
                    self.operate.config_and_deploy_role(
                        sub_computer_id_list, cpu, self.vbs_memory)
        return compute_id_list

    def divide_host_by_group(self, compute_id_list):
        """
        根据DWS定义参数aggregate_vbs_cpu_reserve字段host_group1:4,host_grou2:8;host_group3划分不同的group组，区分不同的cpu隔离值
        如果没有该字段，按照原逻辑进行配置
        """
        group_host_id_list_cpu = GeneralQuery.get_host_group_info(self.db, self.project_id,
                                                                  self.pod_id, vbs_cpu=self.vbs_cpu)
        result = list()
        remain_compute_id_list = compute_id_list[:]

        # 过滤非本次添加的节点
        for sub_host_list, sub_cpu in group_host_id_list_cpu:
            common_id_set = set(remain_compute_id_list) & set(sub_host_list)
            if common_id_set:
                result.append((list(common_id_set), sub_cpu))
                remain_compute_id_list = list(set(remain_compute_id_list) - common_id_set)

        if remain_compute_id_list:
            result.append((remain_compute_id_list, self.vbs_cpu))
        return result

    def config_vbs_osd_node_role(self):
        compute_storage_id_list = list()
        if self.vbs_osd_bmc_ip_list:
            compute_storage_id_list, compute_storage_ip_list = \
                self.cps_host_client.get_host_info(self.vbs_osd_bmc_ip_list)

            # 已经安装过的节点，重启角色，兼容IPSAN等场景提前部署角色，然后跳过后续安装
            if self.operate.check_fusionstorage_block_before_install_role(
                    self.cps_rest_client, compute_storage_id_list):
                logger.info('Restart config and install role for osd '
                            'nodes[%s]' % compute_storage_ip_list)
                self.operate.restart_fusionstorage_block_template(
                    self.cps_rest_client, compute_storage_id_list)
            else:
                logger.info('Start config and install role for osd '
                            'nodes[%s], cpu[%s], memory[%s]' %
                            (compute_storage_ip_list, self.osd_cpu,
                             self.osd_memory))
                self.operate.config_and_deploy_role(
                    compute_storage_id_list, self.osd_cpu, self.osd_memory)
        return compute_storage_id_list

    def cleanup(self):
        logger.info("Start cleanup")
        if not self.vbs_list:
            logger.error("There is no vbs node need cleanup.")
            return
        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)

        logger.info("1.Stop fusionstorage-blockXXX role nodes[%s]" % str(vbs_host_ip_list))
        self.operate.stop_fusionstorage_block_template(self.cps_rest_client, vbs_host_id_list)

        logger.info("2.Cleaning up fusionstorage-blockXXX role nodes[%s]" % str(vbs_host_ip_list))
        self.operate.remove_fusionstorage_block_role(self.cps_rest_client, vbs_host_id_list)

        logger.info("3.Checking fusionstorage-blockXXX role nodes[%s]" % str(vbs_host_ip_list))
        self.operate.check_fusionstorage_block_on_host(self.cps_rest_client, vbs_host_id_list)
