#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
import utils.common.log as logger
from utils.DBAdapter.DBConnector import BaseOps
from plugins.DistributedStorage.scripts.logic.DeployOperate import DeployOperate
from plugins.DistributedStorage.scripts.utils.common.DeployConstant import DeployConstant


class DealInfoForCMDB(object):

    def __init__(self, project_id, pod_id, fs_args):
        self.fs_args = fs_args
        self.float_ip = self.fs_args.get('float_ip')
        self.project_id = project_id
        self.pod_id = pod_id
        self.db = BaseOps()
        self.opr = DeployOperate(float_ip=self.float_ip)
        self.plane_dict = {
            'management_internal': "External_om",
            'storage_backend': 'Storage_data0',
            'replication': "replication",
            'quorum': "quorum"
        }

    @staticmethod
    def get_ip_address(node, plane_dict):
        ip_addresses = []
        for ip_info in node.get('ip_address_list'):
            if ip_info['ip_usage'] == ['unknown']:
                continue
            for usage in ip_info["ip_usage"]:
                if usage not in plane_dict:
                    continue
                net_info = {
                    "netPlane": plane_dict[usage],
                    "ip": str(ip_info['ip_address']),
                    "gateway": str(ip_info['default_gateway']),
                    "netMask": str(ip_info['subnet_prefix']),
                }
                ip_addresses.append(net_info)
        return ip_addresses

    @staticmethod
    def get_services_info(version, region_id, osd_host_names, vm_hostnames):
        """
        组装微服务参数
        """
        service_info = [
            {
                "indexName": DeployConstant.CLOUD_SERVICE_INDEX,
                "version": version,
                "regionCode": region_id,
                "extendInfos": [
                    {
                        "key": "Distributed-storage",
                        "value": "True"
                    }
                ],
                "components": [
                    {
                        "indexName": 'FSM',
                        "version": version,
                        "nodeNames": vm_hostnames
                    },
                    {
                        "indexName": 'FSA',
                        "version": version,
                        "nodeNames": osd_host_names
                    }
                ]
            }
        ]
        return service_info

    def tool_logout(self):
        logger.info("rest client logout, client ip:%s" % str(self.float_ip))
        self.opr.logout()

    def tool_login(self, ):
        """
        rest client 登录
        :return:
        """
        logger.info("rest client login, client ip:%s" % str(self.float_ip))
        self.opr.login(DeployConstant.DM_LOGIN_USER, self.fs_args['dm_update_pwd'])

    def get_name(self):
        """
        返回集群name
        :return: str
        """
        return DeployConstant.CLOUD_SERVICE_INDEX + "_" + self.get_esn()

    def get_node_info(self):
        """
        获取和构造节点信息 按照cmdb的接口要求
        :return: "deployNodeInfos":[
        {
            "name":"",
            "ipAddresses":[
                {
                    "netPlane":"",
                    "ip":"",
                    "gateway":"",
                    "netMask":"",
                }
            ],
            "floatIpAddresses":[
                {
                    "floatIp":"",
                    "fixedIp":"",
                    "cloudServiceIndex":""
                }
            ]
        }
        ]
        """
        plane_dict = self.plane_dict
        fsm_list = []
        deploy_node_infos = []
        result = self._parse_rest()
        for node in result:
            if "management" in node['role']:
                # 浮动ip部分
                fsm_list.append(str(node['management_internal_ip']))
                continue
            item = {"name": str(node.get('name'))}
            # 节点信息部分
            ip_addresses = self.get_ip_address(node, plane_dict)
            item.update({'ipAddresses': ip_addresses})
            logger.info("get node success. detail:%s" % str(item))
            deploy_node_infos.append(item)
        if not fsm_list:
            logger.error("FSM list length is zero.")
            raise Exception("FSM list length is zero.")
        elif len(fsm_list) > 1:
            fsm_primary_ip = fsm_list[0]
            fsm_slave_ip = fsm_list[1]
        else:
            fsm_primary_ip = fsm_list[0]
            fsm_slave_ip = fsm_list[0]
        return deploy_node_infos, [fsm_primary_ip, fsm_slave_ip]

    def get_fsm_node_info(self, master_fsm, standby_fsm):
        """
        获取和构造节点信息 按照cmdb的接口要求(管理高可用改造工程，FSM虚拟机需要注册CMDB)
        :return:
        """
        deploy_node_infos = []
        node_name = dict()
        if master_fsm:
            node_name.update({master_fsm.get("om_ip"): master_fsm.get("hostname")})
        if standby_fsm:
            node_name.update({standby_fsm.get("om_ip"): standby_fsm.get("hostname")})
        if not node_name:
            return deploy_node_infos
        plane_dict = self.plane_dict
        result = self._parse_rest()
        for node in result:
            if "management" in node['role']:
                current_node_ip = node.get("management_internal_ip")
                if not node_name.get(current_node_ip):
                    continue
                item = {"name": str(node_name.get(current_node_ip))}
                ip_addresses = self.get_ip_address(node, plane_dict)
                item.update({'ipAddresses': ip_addresses})

                logger.info("get node success. detail:%s" % str(item))
                deploy_node_infos.append(item)
        return deploy_node_infos

    def get_version(self):
        url = DeployConstant.HTTPS + self.float_ip + ":" + DeployConstant.PORT + DeployConstant.VERSION
        logger.info("get version url is: %s." % url)
        res = self.opr.rest_client.normal_request(url, 'get').json()
        status, result = res.get('result').get('code'), res.get('data')
        if status == 0:
            logger.info("get version success.detail:%s" % str(res))
            return str(result.get('version'))
        raise Exception('get version fail.detail:%s' % str(res))

    def get_esn(self):
        url = DeployConstant.HTTPS + self.float_ip + ":" + DeployConstant.PORT + DeployConstant.ESN
        logger.info("get ens url is: %s." % url)
        res = self.opr.rest_client.normal_request(url, 'get').json()
        status, result = res.get('result').get('code'), res.get('data')
        if status == 0:
            logger.info("get esn success.detail:%s" % str(res))
            return str(result.get('esn'))
        raise Exception("get esn fail.detail:%s" % str(res))

    def _parse_rest(self):
        """
        POST：https://${float_ip}:${port}/api/v2/network_service/servers -> DeployConstant.NET_SERVICE
        :param float_ip: DistributedStorage float_ip
        :return: all node net info
        """
        url = DeployConstant.HTTPS + self.float_ip + ":" + DeployConstant.PORT + DeployConstant.NET_SERVICE
        logger.info("get node info url is: %s." % url)
        res = self.opr.rest_client.normal_request(url, 'post', {}).json()
        status, result = res.get('result').get('code'), res.get('data')
        if status == 0:
            logger.info("get node info success.detail:%s" % str(res))
            return result
        raise Exception('get node info fail. detail:\n %s' % str(res))
