#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
from platforms.project.ProjectUtils import get_project_condition_boolean
import utils.common.log as logger
from utils.DBAdapter.DBConnector import BaseOps
from utils.business.param_util import ParamUtil
from utils.business.manageone_cmdb_util import ManageOneCmdbUtil
from utils.common.fic_base import StepBaseInterface
from utils.common.message import Message
from utils.common.exception import FCDException
from plugins.DistributedStorage.scripts.logic.vm_operate import VMOperate
from plugins.DistributedStorage.scripts.utils.common.DeployConstant import DeployConstant
from plugins.DistributedStorage.scripts.utils.common.query_for_cmdb import DealInfoForCMDB
from plugins.DistributedStorage.scripts.utils.interface.DistributedStorage import DistributedStorageArgs

logger.init("business DistributedStorage RegisterCMDB")


class FSB8RegisterCMDB(StepBaseInterface):
    def __init__(self, project_id, pod_id):
        super(FSB8RegisterCMDB, self).__init__(project_id, pod_id)
        self.project_id = project_id
        self.pod_id = pod_id
        self.db = BaseOps()
        self.service_name = 'DistributedStorageBusiness'
        self.param_util = ParamUtil()
        self.vm_operate = VMOperate(self.project_id, self.pod_id, None)
        self.region_code = self.param_util.get_param_value(self.pod_id, self.service_name, 'region0_id')
        self.storage_tool = DistributedStorageArgs(self.project_id, self.pod_id)

    def pre_check(self, project_id, pod_id):
        """
        插件内部接口：执行安装前的资源预检查，该接口由execute接口调用，工具框架不会直接调用此接口。
        :param project_id:
        :param pod_id:
        :return:
        """
        return Message(200)

    def rollback(self, project_id, pod_id):
        """
        标准调用接口：执行回滚
        :param project_id:
        :param pod_id:
        :return:Message类对象
        """
        return Message(200)

    def retry(self, project_id, pod_id):
        """
        标准调用接口：重试
        :return: Message类对象
        """
        self.rollback(project_id, pod_id)
        return self.execute(project_id, pod_id)

    def check(self, project_id, pod_id):
        """
        标准调用接口：重试
        :param project_id:
        :param pod_id:
        :return:
        """
        return Message(200)

    def execute(self, project_id, pod_id):
        """
        标准调用接口：执行安装前预检查&安装&配置
        :param project_id:
        :param pod_id:
        :return:Message类对象
        """
        try:
            self.set_cmdb_info(project_id, pod_id)
            return Message(200)
        except FCDException as e:
            logger.error(e)
            return Message(500, e)
        except Exception as e:
            logger.error(e)
            return Message(500, FCDException("626267", str(e)))

    def set_cmdb_info(self, project_id, pod_id):
        """
        业务存储微服务分为FSM和FSA。FSM拓扑视图下包含主备虚拟机，FSA拓扑视图下包含存储节点
        """
        logger.info("start to set FSB800 cmdb info.")
        # 构造云服务信息
        deployment_type = ""
        if get_project_condition_boolean(self.project_id, 'TenantStorFB80'):
            deployment_type = "separate"
        if get_project_condition_boolean(self.project_id, 'TenantStorFBHCI80'):
            deployment_type = "converge"
        float_ip = self.storage_tool.get_business_storage_float_ip()
        logger.info("get business storage float ip success.detail: %s." % float_ip)
        dm_update_pwd = self.storage_tool.get_business_fsm_portal_pwd()
        fs_args = {'float_ip': float_ip, 'dm_update_pwd': dm_update_pwd}
        cloud_service = self.assemble_cloud_service_info(fs_args, deployment_type)
        # 设置云服务信息
        mo_cmdb = ManageOneCmdbUtil(self.project_id, self.pod_id)
        mo_cmdb.set_cloud_service_info_v3(self.region_code, cloud_service)
        logger.info("current az_id :%s.set DistributedStorage cmdb info successfully!" % self.get_az_id())

    def get_az_id(self):
        """
        返回业务存储所在az id
        :return:
        部署首region，从region时，Type2,Type3:openstack_region，Type1：cascaded_region
        扩AZ时，新建的AZ ID：Type2/3：openstack_expansion_az，Type1：cascaded_expansion_azk
        """
        az_id = self.param_util.get_param_value(self.pod_id, self.service_name, 'openstack_expansion_az')
        if not az_id:
            logger.info("get az_id from openstack_region")
            az_id = self.param_util.get_param_value(self.pod_id, self.service_name, 'openstack_region')
        return az_id

    def assemble_cloud_service_info(self, float_dic, deployment_type):
        """
        生成注册cmdb信息
        """
        float_ip = float_dic.get('float_ip')
        if not float_ip:
            return float_ip
        deal_tool = DealInfoForCMDB(self.project_id, self.pod_id, float_dic)
        deal_tool.tool_login()
        deploy_node_infos, fsm_list = deal_tool.get_node_info()
        business_nodes_info = self.db.get_install_os_list_info(self.pod_id)
        business_nodes_list = [node.get("bmc_ip") for node in business_nodes_info]
        osd_host_names = [node.get("hostname") for node in business_nodes_info]

        master_fsm, standby_fsm = self.vm_operate.get_vm_data(self.pod_id, float_ip)
        vm_hostnames = [master_fsm.get('hostname'), standby_fsm.get('hostname')]

        deployed_bmc_ips = ";".join(business_nodes_list)
        version = deal_tool.get_version()
        service_info = deal_tool.get_services_info(version, self.region_code, osd_host_names, vm_hostnames)
        cloud_service = {
            "indexName": DeployConstant.CLOUD_SERVICE_INDEX,
            "version": version,
            "name": deal_tool.get_name(),
            "extendInfos": [
                {'key': "az_id", "value": self.get_az_id()},
                {'key': "deployment_type", "value": deployment_type},
                {"key": "fsm_float_ip", "value": float_ip},
                {"key": "fsm_primary_ip", "value": fsm_list[0]},
                {"key": "fsm_slave_ip", "value": fsm_list[1]},
                {"key": "deploy_bmc_node", "value": deployed_bmc_ips}
            ],
            "deployNodeInfos": deploy_node_infos,
            "services": service_info
        }
        logger.info("get param cloud_service: %s" % str(cloud_service))
        logger.info("get param region_id: %s" % str(self.region_code))
        deal_tool.tool_logout()
        return cloud_service
