# -*- coding: utf-8 -*-
import utils.common.log as logger
from utils.business.manageone_cmdb_util import ManageOneCmdbUtil
from plugins.DistributedStorage.logic.InstallOperate import BaseOps
from utils.common.fic_base import StepBaseInterface
from utils.business.install_csp_agent import CSPAgent
from utils.common.fic_common import GetConfig
from utils.common.message import Message
from utils.business.param_util import ParamUtil
from utils.security.crypt import decrypt
from utils.common.exception import HCCIException
import traceback


class InstallCspAgent(StepBaseInterface):
    def __init__(self, project_id, pod_id):
        StepBaseInterface.__init__(self, project_id, pod_id)
        self.project_id = project_id
        self.pod_id = pod_id
        self.db = BaseOps()
        self.param_util = ParamUtil()
        self.mo_cmdb_util = ManageOneCmdbUtil(project_id, pod_id)
        # 获取虚机登录密码
        # 1、服务新安装时密码读取默认密码；
        # 2、服务安装后扩CSP，则读取统一密码里的密码，在scene/hcs/typeN/user_lld_parameter/param_details.cfg里配置
        self.value_list = self.db.get_user_input_cloud_param_by_key(
            self.project_id, "fusionstorage_manager_password")
        self.user_name = "fsadmin"

    def pre_check(self, project_id, pod_id):
        """
        插件内部接口：执行安装前的资源预检查，该接口由execute接口调用，工具框架不会直接调用此接口。
        :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.pre_check(project_id, pod_id)
            logger.info("begin to install CSP Agent")
            self._deploy_agent()
        except HCCIException as e:
            logger.error(traceback.format_exc())
            return Message(500, e)
        except Exception as e:
            logger.error(traceback.format_exc())
            return Message(500, HCCIException(626065, str(e)))
        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类对象
        """
        return self.execute(self.project_id, self.pod_id)

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

    def list_to_dict(self):
        dic = dict()
        if self.value_list:
            values = self.value_list.strip().split(",")
            for i in range(2, len(values), 3):
                ip = values[i - 2]
                dic[ip] = (values[i - 1], values[i])
        return dic

    def _deploy_agent(self):
        # 获取regionId，也要保住该参数不依赖服务，直接读取LLD里的regionId
        service_name = ['DistributedStorageBusiness', 'DistributedStorageManage']
        conf_obj = GetConfig(path='/plugins/DistributedStorage/utils/common/config.ini')
        default_user_pwd = decrypt(conf_obj.get_item('default_pwd', 'csp_agent_user_pwd'))
        default_root_pwd = decrypt(conf_obj.get_item('default_pwd', 'csp_agent_root_pwd'))
        fsm_password = self.list_to_dict()
        for name in service_name:
            region_id = self.param_util.get_param_value(self.pod_id, name,
                                                        'region_id', 'region0_id')
            # 通过cmdb查找节点IP信息
            # 注意：禁止使用LLD获取IP，只能通过cmdb处获取IP
            if region_id:
                ip_lst = self.get_ip_by_cmdb(region_id, "FusionStorageBlock")
                if not ip_lst:
                    logger.info("%s service ip lst is empty!" % name)
                    continue
                node_lst = []
                for ip in ip_lst:
                    # 从LLD中获取用户输入的主机IP和密码，如果不存在就使用默认密码
                    user_pwd, root_pwd = fsm_password.get(ip, (default_user_pwd, default_root_pwd))
                    node_info = {
                        "node_ip": ip,
                        "process_username": self.user_name,
                        "user_password": user_pwd,
                        "sudo_cmd": "su",
                        "root_password": root_pwd
                    }
                    node_lst.append(node_info)
                ret_dic = CSPAgent(self.pod_id).install_csp_agent(
                    service_name=name, node_list=node_lst)
                if ret_dic["result_code"] != "0":
                    err_msg = "Install csp agent failed, ip lst: %s, ret %s" \
                              % (ip_lst, ret_dic["result_msg"])
                    raise Exception(err_msg)
                logger.info("Install csp agent success, ip lst: %s" % ip_lst)
        return Message(200)

    def get_ip_by_cmdb(self, region_id: str, index_name: str) -> list:
        """
        通过cmdb获取ip信息
        :param index_name:
        :param region_id: regionId
        :return: ip列表
        """
        node_info_lst = self.mo_cmdb_util.get_cloud_service_info(region_id, index_name=index_name)

        logger.info("Get node info: %s" % str(node_info_lst))
        ip_lst = []
        for node_info in node_info_lst:
            if not node_info:
                continue
            extend_infos = node_info.get("extendInfos")
            for extend_info in extend_infos:
                if extend_info.get("key") == "fsm_primary_ip":
                    ip_lst.append(extend_info.get("value"))
                if extend_info.get("key") == "fsm_slave_ip":
                    ip_lst.append(extend_info.get("value"))
        return ip_lst
