# coding=utf-8
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.

from utils.common.message import Message
from utils.DBAdapter.DBConnector import BaseOps
import utils.common.log as logger
from utils.common.exception import HCCIException
from utils.common.fic_base import StepBaseInterface
from utils.business.OpenStack.openstack_password_utils import DefaultPasswordManager
from utils.business.project_condition_utils import get_project_condition_boolean
from plugins.DistributedStorage.Deploy.scripts.PreCheck.implement.job_expand_node_cache_check import CheckPoolNodeSSD


class CheckPoolNodeSSDIntf(StepBaseInterface):
    def __init__(self, project_id, pod_id):
        super(CheckPoolNodeSSDIntf, 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:
            self.main(pod_id, project_id)
        except HCCIException as e1:
            return Message(500, e1)
        except Exception as e2:
            return Message(500, e2)
        return Message(200)

    def main(self, pod_id, project_id):
        for fs_args in self.fs_args_list:
            for pool_name, nodes in fs_args.get("pool_name_node_map").items():
                logger.info("Start to check the cache of the resource pool:{}".format(pool_name))
                fs_args["ex_osd_list"] = nodes
                check_obj = CheckPoolNodeSSD(project_id, pod_id, fs_args)
                check_obj.procedure()

    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)


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()
    nodes_info = db.get_bmc_info_by_pod_id(pod_id)
    for node in nodes_info:
        node['storage_pool_name_and_slot'] = node.pop('manage_storage_pool_name')
    osd_list = [node for node in nodes_info if "osd" in node.get("ref_component")]
    params_list = list()
    fs_args = dict()
    fs_args['fsm_float_ip'] = db.get_user_input_cloud_param_by_key(project_id, "expansion_fsm_float_ip")
    fs_args['fsm_admin_password'] = db.get_user_input_cloud_param_by_key(project_id, "expansion_fs8_fsm_admin_passwd")
    fs_args['ex_osd_list'] = osd_list
    fs_args['default_pool_name'] = 'murano'
    fs_args['login_user'] = "fsp"
    fs_args['login_passwd'] = DefaultPasswordManager().get_fsp_default_password()
    params_list.append(fs_args)

    if get_project_condition_boolean(project_id, 'RegionConHA|ThreeDCInTwoPlaces'):
        params_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_password'] = dc001_fsm_admin_password
        dc001_fs_args['ex_osd_list'] = dc001_osd_list
        dc001_fs_args['default_pool_name'] = 'murano'
        dc001_fs_args['login_user'] = "fsp"
        dc001_fs_args['login_passwd'] = DefaultPasswordManager().get_fsp_default_password()
        fs_args['pool_name_node_map'] = group_by_pool_name(dc001_osd_list, 'murano')
        params_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_password'] = dc002_fsm_admin_password
        dc002_fs_args['ex_osd_list'] = dc002_osd_list
        dc002_fs_args['default_pool_name'] = 'murano'
        dc002_fs_args['login_user'] = "fsp"
        fs_args['pool_name_node_map'] = group_by_pool_name(dc002_osd_list, 'murano')
        dc002_fs_args['login_passwd'] = DefaultPasswordManager().get_fsp_default_password()
        params_list.append(dc002_fs_args)
    else:
        fs_args['pool_name_node_map'] = group_by_pool_name(osd_list, 'murano')
    return params_list


def group_by_pool_name(osd_list, default_pool):
    import collections
    pool_nodes_map = collections.defaultdict(list)
    for node in osd_list:
        pool_name = node.get("manage_storage_pool_name")
        if pool_name:
            pool_nodes_map[pool_name].append(node)
        else:
            pool_nodes_map[default_pool].append(node)
    return pool_nodes_map
