# coding=utf-8
import utils.common.log as logger
from utils.common.message import Message
from utils.DBAdapter.DBConnector import BaseOps
from utils.common.exception import HCCIException
from utils.common.fic_base import StepBaseInterface
from plugins.DistributedStorage.logic.DeployOperate import FusionStorageOperate
from utils.business.project_condition_utils import get_project_condition_boolean


class CheckPoolNameConflict(StepBaseInterface):
    def __init__(self, project_id, pod_id):
        super(CheckPoolNameConflict, self).__init__(project_id, pod_id)
        self.project_id = project_id
        self.pod_id = pod_id
        self.fs_args_list = get_expand_params(self.project_id, self.pod_id)

    def pre_check(self, project_id, pod_id):
        """
        插件内部接口：执行安装前的资源预检查，该接口由execute接口调用，工具框架不会直接调用此接口。
        :param project_id:
        :param pod_id:
        :return:Message类对象
        """
        return Message(200)

    def execute(self, project_id, pod_id):
        try:
            for fs_args in self.fs_args_list:
                check_obj = CheckPoolName(project_id, pod_id, fs_args)
                check_obj.procedure()
            return Message(200)
        except HCCIException as e1:
            return Message(500, e1)
        except Exception as e2:
            return Message(500, e2)

    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(project_id, pod_id)

    def check(self, project_id, pod_id):
        """
        标准调用接口：重试
        :param project_id:
        :param pod_id:
        :return:Message类对象
        """
        return Message(200)


class CheckPoolName(object):
    def __init__(self, project_id, pod_id, fs_args):
        self.project_id = project_id
        self.pod_id = pod_id
        self.fs_args = fs_args
        self.fsm_float_ip = self.fs_args.get('fsm_float_ip')
        self.fsm_admin_passwd = self.fs_args.get('fsm_admin_passwd')
        self.osd_list = self.fs_args.get('osd_list')

    def procedure(self):
        if get_project_condition_boolean(self.project_id, 'RegionConHA|ThreeDCInTwoPlaces'):
            if not self.osd_list:
                return
        # 新增池场景osd节点至少3个
        if len(self.osd_list) < 3:
            message = "At least three osd nodes are required for creating pools."
            logger.error(message)
            raise Exception(message)
        lld_pool_name = self.get_node_pool_name_list()
        exist_pool_name = self.get_exist_pool_name_list()
        for pool_name in list(set(lld_pool_name)):
            if pool_name in exist_pool_name:
                err_msg = "The pool name [%s] is already in the cluster" % pool_name
                logger.error(err_msg)
                raise Exception(err_msg)

    def get_node_pool_name_list(self):
        """
        获取待扩节点目标存储池名称列表
        采用默认存储池名称
        """
        osd_list = self.osd_list
        if get_project_condition_boolean(self.project_id, 'TenantStorNewPool'):
            pool_name_list = [osd['storage_pool_name_and_slot'] for osd in
                              osd_list]
        else:
            pool_name_list = [osd['manage_storage_pool_name'] for osd in
                              osd_list if osd['manage_storage_pool_name']]
        return pool_name_list


    def get_exist_pool_name_list(self):
        """
        获取已有管理存储池名称列表
        """
        operate = FusionStorageOperate(self.fsm_float_ip)
        login_user = 'admin'
        login_passwd = self.fsm_admin_passwd
        status_code, error_code, error_des = operate.login(
            login_user, login_passwd)
        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)

        logger.info("Query storage pool data.")
        res_pool = operate.query_storage_pool()
        pool_info = res_pool.get_query_data()
        storage_pools = pool_info.get("storagePools")
        if not storage_pools:
            logger.error("check pool fail...")
            raise Exception("check pool fail...")
        pool_name_list = [pool.get('poolName') for pool in storage_pools]

        operate.login_out(login_user, login_passwd)
        return pool_name_list


def get_expand_params(project_id, pod_id):
    """
    获取扩容参数
    :param project_id:
    :param pod_id:
    :return: [fs_args, dc001_fs_args, dc002_fs_args]
    """
    db = BaseOps()
    fs_args_list = list()
    if get_project_condition_boolean(project_id, 'TenantStorNewPool'):
        fs_args = dict()
        fsm_float_ip = db.get_user_input_cloud_param_by_key(project_id, "expansion_az_fsm_float_ip")
        fsm_admin_passwd = db.get_user_input_cloud_param_by_key(project_id, "reuse_fsm_admin_passwd")
        osd_list = db.get_install_os_list_info(pod_id=pod_id)
        fs_args['fsm_float_ip'] = fsm_float_ip
        fs_args['fsm_admin_passwd'] = fsm_admin_passwd
        fs_args['osd_list'] = osd_list
        fs_args_list.append(fs_args)
    else:
        fs_args = dict()
        fsm_float_ip = db.get_user_input_cloud_param_by_key(project_id, "expansion_fsm_float_ip")
        fsm_admin_passwd = db.get_user_input_cloud_param_by_key(project_id, "expansion_fs8_fsm_admin_passwd")
        server_list = db.get_bmc_info_by_pod_id(pod_id=pod_id)
        osd_list = [server for server in server_list if 'osd' in server['ref_component']]
        fs_args['fsm_float_ip'] = fsm_float_ip
        fs_args['fsm_admin_passwd'] = fsm_admin_passwd
        fs_args['osd_list'] = osd_list
        fs_args_list.append(fs_args)
        if get_project_condition_boolean(project_id, 'RegionConHA|ThreeDCInTwoPlaces'):
            fs_args_list = list()
            dc001_fs_args = dict()
            dc001_fsm_float_ip = db.get_user_input_cloud_param_by_key(project_id, "dc001_expansion_fsm_float_ip")
            dc001_fsm_admin_password = db.get_user_input_cloud_param_by_key(project_id,
                                                                            "dc001_expansion_fsm_admin_passwd")
            dc001_osd_list = [node for node in osd_list if "dc001" in node.get("site")]
            dc001_fs_args['fsm_float_ip'] = dc001_fsm_float_ip
            dc001_fs_args['fsm_admin_passwd'] = dc001_fsm_admin_password
            dc001_fs_args['osd_list'] = dc001_osd_list
            fs_args_list.append(dc001_fs_args)

            dc002_fs_args = dict()
            dc002_fsm_float_ip = db.get_user_input_cloud_param_by_key(project_id, "dc002_expansion_fsm_float_ip")
            dc002_fsm_admin_password = db.get_user_input_cloud_param_by_key(project_id,
                                                                            "dc002_expansion_fsm_admin_passwd")
            dc002_osd_list = [node for node in osd_list if "dc002" in node.get("site")]
            dc002_fs_args['fsm_float_ip'] = dc002_fsm_float_ip
            dc002_fs_args['fsm_admin_passwd'] = dc002_fsm_admin_password
            dc002_fs_args['osd_list'] = dc002_osd_list
            fs_args_list.append(dc002_fs_args)
    return fs_args_list
