# -*- coding: utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
import os

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 utils.business.OpenStack.cps_pkg_uploader import CpsPkgUploader
from utils.business.project_condition_utils import get_project_condition_boolean
from plugins.ManageOne.scripts.utils.get_solution import get_solution
from plugins.DistributedStorage.logic.install_operate import InstallOperate
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.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.more_args = kwargs
        self.progress_deploy = get_solution()
        self.pkg_file_path = fs_args.get("uvp_install_path")
        self.vbs_list = fs_args.get('vbs_list')
        self.iscsi_condition = get_project_condition_boolean(self.project_id, 'TenantStorFB_iSCSI')

    def procedure(self):
        logger.info("Install fusionstorage-block role on compute node")
        vbs_bmc_ip_list = [vbs.get('bmc_ip') for vbs in self.vbs_list]
        compute_id_list, compute_ip_list = self.cps_host_client.get_host_info(vbs_bmc_ip_list)
        if not compute_id_list:
            err_msg = "The node list is empty. There is no node to install role"
            logger.error(err_msg)
            if self.iscsi_condition:
                return
            raise Exception(err_msg)
        cps_client = FSPAuthClient.get_cps_rest_client(self.db, self.project_id, self.pod_id)
        if self.operate.check_fusionstorage_block_before_install_role(cps_client, compute_id_list):
            # 已经安装过的节点，重启角色，兼容IPSAN等场景提前部署角色，然后跳过后续安装
            self.operate.restart_fusionstorage_block_template(cps_client, compute_id_list)
            return
        if self.progress_deploy:
            # 进程化部署未创建VM，需要在部署角色前上传安装包
            logger.info("Upload UVP package to cps-web.")
            cps_rest = FSPAuthClient.get_cps_rest_client(self.db, self.project_id, self.pod_id)
            pkg_path = os.path.dirname(self.pkg_file_path)
            pkg_file = os.path.basename(self.pkg_file_path)
            upload_obj = CpsPkgUploader(cps_rest)
            upload_obj.pkg_upload(pkg_file, pkg_path)
            logger.info("Succeed to upload UVP package[%s/%s] to cps-web." % (pkg_path, pkg_file))
        vbs_cpu = 4
        vbs_memory = 7
        vbs_cpu, vbs_memory = self.operate.get_vbs_cpu_by_vm_density(vbs_cpu, vbs_memory)
        for sub_computer_id_list, cpu in self.divide_host_by_group(compute_id_list, vbs_cpu):
            logger.info('Start config and install role for node%s' % sub_computer_id_list)
            self.operate.config_and_deploy_role(sub_computer_id_list, cpu, vbs_memory)

        logger.info('Checking FusionStorage-Agent rpm package')
        self.operate.check_vbs_node_fusionstorage_agent_rpm(self.vbs_list)

    def divide_host_by_group(self, compute_id_list, vbs_cpu):
        """
        根据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=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, vbs_cpu))
        return result

    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)
