# -*- coding: utf-8 -*-
import traceback
from utils.common.fic_base import TestCase
import utils.common.log as logger
from utils.common.message import Message
from utils.common.exception import FCDException
from plugins.DistributedStorage.scripts.logic.DeployOperate import DeployOperate
from plugins.DistributedStorage.scripts.utils.common.DeployConstant import DeployConstant
from platforms.project.ProjectUtils import get_project_condition_boolean


class CreateClient(TestCase):
    def __init__(self, project_id, pod_id, fs_args, condition=None, metadata=None, **kwargs):
        super(CreateClient, self).__init__(project_id, pod_id)
        self.fs_args = fs_args
        self.bmc_info_lists = self.db.get_install_os_list_info(self.pod_id)
        self.fsa_list = self.fs_args.get('fsa_list')
        self.opr = DeployOperate(self.fs_args)
        self.condition = condition
        self.metadata = metadata
        self.more_args = kwargs

    def procedure(self):
        try:
            logger.info("Start to create client.")
            self.login_dm()

            self.check_cluster()

            self.check_pool()

            logger.info("Check whether VBS is installed.")
            fsa_ip_list = self.get_vbs_ip_list()
            if fsa_ip_list:
                logger.info('create VBS client.')
                res_client = self.opr.create_client(fsa_ip_list)
                status_code, result, error_code, error_des = res_client.get_create_client_code()
                if status_code != 200 or result != 0:
                    err_msg = "Failed to Create VBS client, " \
                              "Detail:[status:%s,result:%s,error:%s]%s" % (status_code, result, error_code, error_des)
                    logger.error(err_msg)
                    raise Exception(err_msg)

            self.config_iscsi()

            logger.info('Create VBS client success')
            self.opr.login_out(DeployConstant.DM_LOGIN_USER, self.fs_args['dm_update_pwd'])
        except FCDException as e:
            logger.error(traceback.format_exc())
            return Message(500, e)
        except Exception as e:
            return Message(500, FCDException(626001, str(e)))
        return Message()

    def login_dm(self):
        status_code, error_code, error_des = self.opr.login(
            DeployConstant.DM_LOGIN_USER, self.fs_args['dm_update_pwd'])
        if status_code != 200 or error_code != 0:
            err_msg = "Failed to login deploy manager, " \
                      "Detail:[status:%s,code:%s]%s" % (status_code, error_code, error_des)
            logger.error(err_msg)
            raise Exception(err_msg)

    def check_cluster(self):
        logger.info('Check cluster...')
        res_cluster = self.opr.query_manage_cluster()
        cluster = res_cluster.get_query_data()
        if not cluster.get('clusterName'):
            logger.error('Check cluster fail...')
            raise Exception("Check cluster fail...")
        else:
            logger.error('Check cluster successfully...')

    def check_pool(self):
        logger.info('Check pool...')
        res_pool = self.opr.query_storage_pool()
        pool = res_pool.get_query_data()
        if len(pool.get('storagePools')) == 0:
            logger.error('Check pool fail...')
            raise Exception("Check pool fail...")
        else:
            logger.info('Check pool successfully...')

    def get_vbs_ip_list(self):
        fsa_ip_list = [fsa.get('om_ip') for fsa in self.fsa_list]
        rsp_obj = self.opr.query_cluster_servers()
        rsp_code, rsp_result, rsp_data = rsp_obj.get_rsp_data()
        if rsp_code != 0:
            error_des = rsp_result.get('description')
            error_sgt = rsp_result.get('suggestion')
            err_msg = "Failed to query the node to install vbs, Detail:%s.Suggestion:%s" % (
                error_des, error_sgt)
            logger.error(err_msg)
            raise Exception(err_msg)
        for server in rsp_data:
            ip = server.get('management_ip')
            if ip in fsa_ip_list and "vbs" in server.get('usage'):
                fsa_ip_list.remove(server.get('management_ip'))
                logger.info("VBS has been installed on node[%s]." % ip)
        return fsa_ip_list

    def config_iscsi_switch(self, fsa_manage_ip):
        result = self.opr.config_iscsi_switch(fsa_manage_ip)
        succ_ip = result.get_iscsi_result()
        if not succ_ip:
            err_msg = "Failed to config iscsi switch, fsa ip=%s, " \
                      "result=%s" % (fsa_manage_ip, result.res.json())
            logger.error(err_msg)
            raise Exception(err_msg)

    def config_iscsi(self):
        if not get_project_condition_boolean(self.project_id, 'TenantStorFB_iSCSI'):
            return
        iscsi_configed_count = 0
        for fsa in self.fsa_list:
            fsa_manage_ip = fsa.get('om_ip')
            result = self.opr.query_network_serive(fsa_manage_ip)
            fsa_storage_ip = result.get_storage_ip()
            if not fsa_storage_ip:
                logger.error("fsa_ip= %s, storage ip is null. result=%s" % (fsa_manage_ip, result.res.json()))
                continue
            self.config_iscsi_switch(fsa_manage_ip)
            result = self.opr.add_iscsi_portal(fsa_manage_ip, fsa_storage_ip)
            succ_ip = result.get_iscsi_result()
            if not succ_ip:
                error_code = result.res.json().get('detail')[0].get('errorCode')
                if error_code == 33760258:
                    iscsi_configed_count += 1
                    logger.info("The specified iSCSI IP address already exists on node[%s]." % fsa_manage_ip)
                    continue
                err_msg = "Failed to add iscsi portal, " \
                          "fsa ip=%s, result=%s" % (fsa_manage_ip, result.res.json())
                logger.error(err_msg)
                raise Exception(err_msg)

            iscsi_configed_count += 1
        if 0 == iscsi_configed_count:
            err_msg = "Failed to add iscsi portal for fsa node, count = 0"
            logger.error(err_msg)
            raise Exception(err_msg)
        logger.info('Config iscsi service success, fsa count=%d' % iscsi_configed_count)
