# -*- 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.ssh_util2 import Ssh as sshCmd
from utils.common.fic_base import TestCase
from utils.common.OpenStackNodeManager import OpenStackNodeManager
from utils.business.OpenStack.cps_pkg_uploader import CpsPkgUploader
from utils.client.FSPAuthClient import FSPAuthClient
from utils.constant.FCDConstant import get_compute_dpdk_hosts
from utils.Driver.CloudDC.OpenStack.get_host_info import GetHostInfo
from utils.business.OpenStack.openstack_password_utils import DefaultPasswordManager
from plugins.ManageOne.scripts.utils.get_solution import get_solution
from plugins.DistributedStorage.logic.install_operate import InstallOperate


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_bmc_ip_list = self.get_vbs_ip_list()
        self.scale_cpu = 4
        self.scale_memory = 7

    @classmethod
    def modify_agent_control_file_handler(cls, cmd, host_info: dict, timeout=120):
        host_ip = host_info.get("om_ip")
        try:
            ssh_client = InstallOperate.create_ssh_root_client(
                host_ip, host_info.get('user'), host_info.get('passwd'), host_info.get('root_pwd'))
        except Exception as err:
            return False, host_ip, str(err)
        try:
            ret = sshCmd.ssh_exec_command_return(ssh_client, cmd, timeout=timeout, retry_times=0)
        except Exception as err1:
            return False, host_ip, str(err1)
        if not str(ret).__contains__("last=0"):
            return False, host_ip, str(ret)
        return True, host_ip, str(ret)

    @staticmethod
    def get_host_info_by_bmc(pod_id, host_client, role_bmc_list):
        role_list = list()
        all_cps_hosts = host_client.get_hosts_info()
        for host in all_cps_hosts:
            if host["metadata"].get('ipmiip') is None:
                continue
            for role_bmc in role_bmc_list:
                if role_bmc != host['metadata']['ipmiip']:
                    continue
                node = dict()
                node['bmc_ip'] = role_bmc
                node['om_ip'] = host['omip']
                node['hostname'] = host['id']
                node['user'] = 'fsp'
                node['passwd'] = DefaultPasswordManager().get_fsp_default_password()
                node['root_pwd'] = DefaultPasswordManager().get_root_default_password()
                role_list.append(node)
        return role_list

    @staticmethod
    def unregister_component(ssh_client, component):
        cmd_unreg = "cps-monUnRegisterIdentify -P %s;echo unreg_status=$?" % component
        cmd_res = sshCmd.ssh_exec_command_return(ssh_client, cmd_unreg, 120, 0)
        logger.info("Run cmd[%s], result: %s" % (cmd_unreg, str(cmd_res)))
        if ssh_client:
            sshCmd.ssh_close(ssh_client)

    def get_vbs_ip_list(self):
        x86_arm_compute_role_list = get_compute_dpdk_hosts()
        # 筛选适合的计算节点
        tsfb_compute_bmc_ip_list = OpenStackNodeManager.get_bmc_ip_by_role_list(
            self.db, self.pod_id, x86_arm_compute_role_list)
        return tsfb_compute_bmc_ip_list

    def procedure(self):
        if len(self.vbs_bmc_ip_list) == 0:
            logger.info("Openstack compute node not exist, skip to install role.")
            return
        logger.info("Upload UVP package to cps-web.")
        cps_web_client = 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_web_client)
        upload_obj.pkg_upload(pkg_file, pkg_path)
        logger.info("Succeed to upload UVP package[%s/%s] to cps-web." % (pkg_path, pkg_file))

        logger.info("Install fusionstorage-block role on bmc compute node:%s" % self.vbs_bmc_ip_list)
        compute_id_list, compute_ip_list = self.cps_host_client.get_host_info(self.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)
            raise Exception(err_msg)
        logger.info('Start config and install role for node%s' % compute_ip_list)
        vbs_cpu, vbs_memory = self.operate.get_vbs_cpu_by_vm_density(self.scale_cpu, self.scale_memory)
        self.operate.config_and_deploy_role(compute_id_list, vbs_cpu, vbs_memory)

        logger.info('Checking FusionStorage-Agent rpm package')
        host_list = self.get_host_info_by_bmc(self.pod_id, self.cps_host_client, self.vbs_bmc_ip_list)
        self.operate.check_vbs_node_fusionstorage_agent_rpm(host_list)

        logger.info("Stop fusionstorage-blockXXX role nodes%s" % str(compute_ip_list))
        self.operate.stop_fusionstorage_block_template(cps_web_client, compute_id_list)

    def cleanup(self):
        compute_id_list, compute_ip_list = self.cps_host_client.get_host_info(self.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(compute_ip_list))
        self.operate.stop_fusionstorage_block_template(cps_client, compute_id_list)
        logger.info("Cleaning up fusionstorage-blockXXX role nodes%s" % str(compute_ip_list))
        self.operate.remove_fusionstorage_block_role(cps_client, compute_id_list)
        logger.info("Checking fusionstorage-blockXXX role nodes%s" % str(compute_ip_list))
        self.operate.check_fusionstorage_block_on_host(cps_client, compute_id_list)

    def unregister_cloud_agent(self):
        host_list = self.get_host_info_by_bmc(self.pod_id, self.cps_host_client, self.vbs_bmc_ip_list)
        for host in host_list:
            om_ip = host.get('om_ip')
            user = host.get('user')
            password = host.get('passwd')
            root_pwd = host.get('root_pwd')
            logger.info("unregister cloud_agent on node[%s]" % om_ip)
            ssh_client = InstallOperate.create_ssh_root_client(om_ip, user, password, root_pwd)
            self.unregister_component(ssh_client, 'cloud_agent')

    def modify_agent_control_file(self):
        """
        修改FusionStorage-AgentControl文件,确保预留资源场景组件不告警
        :return:
        """
        if not self.vbs_bmc_ip_list:
            return
        logger.info("Start to modify the FusionStorage-AgentControl file on VBS nodes")

        cmd = "line=`grep -an \"STATUS)\" /usr/bin/FusionStorage-AgentControl | " \
              "awk -va=4 -F \"-|:\" '{print $1+a}'`;sed -i \"${line}i return 0\" " \
              "/usr/bin/FusionStorage-AgentControl;echo last=$?"
        host_list = self.get_host_info_by_bmc(self.pod_id, self.cps_host_client, self.vbs_bmc_ip_list)
        res = InstallOperate.multi_thread_exec_cmd(host_list, self.modify_agent_control_file_handler, cmd, timeout=120)
        if res:
            err_msg = "Failed to modify the FusionStorage-AgentControl file on some nodes, details:{}"
            logger.error(err_msg + "details:{}".format(res))
            raise Exception(err_msg + ":{}".format(list(res.keys())))
        logger.info("The FusionStorage-AgentControl file on all nodes are modified successfully")
