# -*- coding: utf-8 -*-
"""
Storage 升级后检查是否需要注册同意密管理
"""
import time
import secrets

from plugins.DistributedStorage.common.ParameterGain import ParamsGain
from plugins.DistributedStorage.Upgrade.scripts.impl.TC_Install_ICAgent import InstallICAgent
from plugins.DistributedStorage.Upgrade.scripts.impl.TC_Reg_Account_To_Unify_Pwd import RegAccountToUnifyPwd
from plugins.DistributedStorage.common.constants import UnifyPwdInfo
from plugins.DistributedStorage.common.constants import SERVICE_NAME
from utils.business.param_util import ParamUtil
from utils.common.exception import HCCIException
from utils.common.fic_base import StepBaseInterface
from utils.business.unite_password.unite_pwd_api import UnitePwdApi
from utils.business.project_util import ProjectApi
from utils.common.message import Message
import utils.common.log as logger


COMPONENT_NAME = UnifyPwdInfo.COMPONENT_NAME
SUB_COMPONENT_NAME = UnifyPwdInfo.SUB_COMPONENT_NAME


class RegUnifyPwd(StepBaseInterface):
    """
    upgrade class
    """
    def __init__(self, project_id, pod_id, regionid_list, suit_id=None):
        super(RegUnifyPwd, self).__init__(project_id, pod_id, regionid_list)
        self.fs_args = ParamsGain(project_id, pod_id,
                                  regionid_list).get_args(suit_id)
        self.fs_args['region_id'] = regionid_list[0]
        self.fs_args['component_name'] = COMPONENT_NAME
        self.fs_args['sub_component_name'] = SUB_COMPONENT_NAME
        self.project_id = project_id
        self.region_id = regionid_list[0]
        self.suit_id = suit_id
        self.params_util = ParamUtil()
        self.project_api = ProjectApi()

    def execute(self, project_id, pod_id, regionid_list=None, suit_id=None):
        """
        标准调用接口：注册统一密码管理
        :param project_id:
        :param pod_id:
        :param regionid_list:
        :return:Message类对象
        """
        logger.info("Strat to register unified passwd management")
        try:
            self.deploy_lock()
            fsm_ips = [self.fs_args.get("master_ip"), self.fs_args.get("slaver_ip")]
            unreg_ip = self.get_dynamic_param(project_id,
                                              self.fs_args.get('region_id'), fsm_ips)
            if not unreg_ip:
                logger.info("No need to register unified passwd management.")
                return Message(200)
            logger.info("Host [%s] need to register unified passwd management." % unreg_ip)
            self.fs_args["fsm_list"] = unreg_ip
            InstallICAgent(project_id, pod_id, self.fs_args).run()
            RegAccountToUnifyPwd(project_id, pod_id, self.fs_args).run()
            return Message(200)
        except HCCIException as e:
            logger.error(e)
            return Message(500, e)
        except Exception as e:
            logger.error(e)
            return Message(500, e)
        finally:
            self.deploy_unlock()

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

    @staticmethod
    def get_dynamic_param(project_id, region_id, fsm_ips):
        """
        查询当前集群fsm节点是否需要注册统一密码管理
        param project_id:
        param region_id:
        param fsm_ips:
        return unreg_ip:需要注册的ip
        """
        unite_pwd_api = UnitePwdApi(project_id)
        account_list = [('fsadmin', 1), ('root', 1)]
        unreg_ip = []
        try:
            for ip in fsm_ips:
                accounts_info = unite_pwd_api.get_account_info(
                    region_id, account_list, '', COMPONENT_NAME,
                    SUB_COMPONENT_NAME, ip)
                if not accounts_info.get('data'):
                    unreg_ip.append(ip)
            return unreg_ip
        except Exception as e:
            err_msg = "Failed to obtain the dynamic params, Detail: %s" % e
            logger.error(err_msg)
            raise Exception(err_msg)

    def deploy_lock(self):
        """
        ICAgentDeployStatus 为0时，表示当前没有任务执行，为1是表示有任务执行。查询任务状态之前，使用0-20秒内随机数等待时间
        """
        gen_random = secrets.SystemRandom()
        random_time = gen_random.randint(0, 20)
        logger.info("Sleep %ss, and check deploy status." % random_time)
        time.sleep(random_time)
        timeout = 3600
        while timeout >= 0:
            deploy_status = self.params_util.get_value_from_cloud_param(
                self.project_id, SERVICE_NAME, "ICAgentDeployStatus", self.region_id)
            if int(deploy_status) == 0:
                self.params_util.set_service_cloud_param(
                    self.project_id, SERVICE_NAME, self.region_id, "ICAgentDeployStatus", 1)
                break
            random_time = gen_random.randint(20, 40)
            time.sleep(random_time)
            timeout -= random_time
            logger.info("Other deploy ICAgent task is running, wait %ss retry...." % random_time)
        if timeout <= 0:
            raise HCCIException(621017)

    def deploy_unlock(self):
        self.params_util.set_service_cloud_param(
            self.project_id, SERVICE_NAME, self.region_id, "ICAgentDeployStatus", 0)
