# -*- coding: utf-8 -*-
import time

import utils.common.log as logger
from utils.common.fic_base import TestCase
from utils.client.FSPAuthClient import FSPAuthClient
from utils.Driver.CloudDC.OpenStack.get_host_info import GetHostInfo
from plugins.DistributedStorage.scripts.logic.InstallOperate import InstallOperate


class InstallRole(TestCase):
    def __init__(self, project_id, pod_id, fs_args, condition=None, metadata=None, **kwargs):
        super(InstallRole, self).__init__(project_id, pod_id)
        self.fs_args = fs_args
        self.operate = InstallOperate(self.project_id, self.pod_id, self.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.condition = condition
        self.metadata = metadata
        self.more_args = kwargs
        self.osd_cpu = fs_args.get('osd_cpu')
        self.osd_memory = fs_args.get('osd_memory')
        self.vbs_cpu = fs_args.get('vbs_cpu')
        self.vbs_memory = fs_args.get('vbs_memory')
        self.osd_bmc_ip_list = fs_args.get('vbs_osd_bmc_ip_list')
        self.not_osd_bmc_ip_list = fs_args.get('vbs_bmc_ip_list')

    def procedure(self):
        # 1. 配置osd云服务节点fusionstorage-blockXXX角色
        logger.info('Start clone and config fusionstorage-blockXXX')
        osd_id_list = list()
        if len(self.osd_bmc_ip_list) > 0:
            osd_id_list, osd_ip_list = self.cps_host_client.get_host_info(self.osd_bmc_ip_list)
            logger.info('Start install role for osd node[bmc:%s, omip:%s]' % (self.osd_bmc_ip_list, osd_ip_list))
            self.operate.config_and_deploy_role(osd_id_list, self.osd_cpu, self.osd_memory)

        # 2. 配置非osd云服务节点 fusionstorage-blockXXX角色
        vbs_id_list = list()
        if len(self.not_osd_bmc_ip_list) > 0:
            vbs_id_list, vbs_ip_list = self.cps_host_client.get_host_info(self.not_osd_bmc_ip_list)
            logger.info('Start install role for vbs node[bmc:%s, omip:%s]' % (self.not_osd_bmc_ip_list, vbs_ip_list))
            self.operate.config_and_deploy_role(vbs_id_list, self.vbs_cpu, self.vbs_memory)

        if not osd_id_list and not vbs_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('Checking FusionStorage-Agent rpm package[%s]' % self.fs_args.get('fsa_list'))
        self.operate.check_fusionstorage_agent_rpm(self.fs_args.get('fsa_list'))

    def cleanup(self):
        vbs_bmc_ip_list = [vbs.get('bmc_ip') for vbs in self.fs_args.get('vbs_list')]
        vbs_host_id_list, vbs_host_ip_list = self.cps_host_client.get_host_info(vbs_bmc_ip_list)
        cps = FSPAuthClient.get_cps_rest_client(self.db, self.project_id, self.pod_id)
        logger.info("Start to clean up fusionstorage-blockXXX role nodes%s" % str(vbs_host_ip_list))
        logger.info("Targeting hosts ids%s" % str(vbs_host_id_list))
        len_hosts = len(vbs_host_id_list)
        while len_hosts > 0 and len(vbs_host_id_list) > 0:
            host_id = vbs_host_id_list[0]
            role = InstallOperate.get_role_on_host(cps, host_id)
            if not role:
                vbs_host_id_list.remove(host_id)
                len_hosts -= 1
                logger.info("There is no fusionstorage-blockXXX role on host[%s]" % host_id)
                continue

            resp = cps.do_role_host_list(role)
            host_list = resp.get('hosts')
            host_id_list = list(set(host_list).intersection(set(vbs_host_id_list)))
            logger.info("Removing role[%s] on hosts%s" % (role, host_id_list))
            cps.do_role_host_delete(role, host_id_list)
            cps.do_commit()
            time.sleep(30)

            vbs_host_id_list = list(set(vbs_host_id_list).difference(host_id_list))
            logger.info("List of remaining hosts%s" % vbs_host_id_list)

            resp = cps.do_role_host_list(role)
            last_host_list = resp.get('hosts')
            if len(last_host_list) == 0:
                logger.info("Deleting role[%s]" % role)
                cps.do_role_delete(role)
            cps.do_commit()
            len_hosts -= 1
        logger.info("Finish to remove role on nodes%s" % vbs_host_ip_list)
