# -*- coding: utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
import re
import utils.common.log as logger
from utils.common.exception import HCCIException
from plugins.DistributedStorage.logic.deploy_operate import DeployOperate
from plugins.DistributedStorage.utils.common.deploy_constant import DeployConstant

ENABLE_STATUS = 0
DISABLE_STATUS = 1


class SandBoxHandlerForUpgrade:
    def __init__(self, fs_args: dict):
        self.fs_args = fs_args
        self.opr = DeployOperate(self.fs_args)
        self.sandbox_initial_status = {}
        self.fsm_node = []
        self.request_body = {}
        self.is_after_813 = False
        self.version = None
        self.setup()

    def setup(self):
        self.opr.login(DeployConstant.DM_LOGIN_USER, self.fs_args.get("password"))
        self.is_after_813 = self.storage_version_after_813()
        if not self.is_after_813:
            return
        self.get_fsm_nodes_sandbox_status()
        self.request_body[self.fs_args.get("master_ip")] = {'node_ips': [self.fs_args.get("master_ip")],
                                                            'root_password': self.fs_args.get("master_root_pwd"),
                                                            'admin_password': self.fs_args.get("password")}
        self.request_body[self.fs_args.get("slaver_ip")] = {'node_ips': [self.fs_args.get("slaver_ip")],
                                                            'root_password': self.fs_args.get("slaver_root_pwd"),
                                                            'admin_password': self.fs_args.get("password")}

    def get_fsm_nodes_sandbox_status(self):
        rsp_obj = self.opr.query_cluster_servers()
        rsp_code, rsp_result, rsp_data = rsp_obj.get_rsp_data()
        if rsp_code != 0 or rsp_result.get('code') != 0:
            err_msg = "Failed to query cluster nodes info, Error: {}".format(rsp_result)
            logger.error(err_msg)
            raise Exception(err_msg)
        for server in rsp_data:
            node_role = server.get('role')
            if 'management' not in node_role:
                continue
            node_ip = server.get('management_ip')
            self.fsm_node.append(node_ip)
            self.sandbox_initial_status[node_ip] = server.get('sandbox_status')

        if len(self.sandbox_initial_status) != 2:
            err_msg = "The status of some nodes is not queried. The node whose status is queried:{}".format(
                self.sandbox_initial_status)
            logger.error(err_msg)
            raise Exception(err_msg)

        logger.info("Sandbox status on FSM nodes:{}".format(self.sandbox_initial_status))

    def recovery_sandbox_status(self):
        logger.info("recovery sandbox status")
        self.opr.check_session_and_retry_login(DeployConstant.DM_LOGIN_USER, self.fs_args.get("password"))
        for ip_addr, sandbox_status in self.sandbox_initial_status.items():
            if sandbox_status == ENABLE_STATUS:
                self.do_enable_fsm_sandbox([ip_addr])
            else:
                self.do_disable_fsm_sandbox(self.request_body.get(ip_addr))

    def enable_fsm_sandbox(self):
        logger.info('Enable fsm sandbox')
        self.do_enable_fsm_sandbox(self.fsm_node)

    def disable_fsm_sandbox(self):
        logger.info("Disable fsm sandbox")
        for body in self.request_body.values():
            self.do_disable_fsm_sandbox(body)

    def storage_version_after_813(self):
        version_regular1 = r"^8.1.(RC[5-9]|[3-9]|([3-9].(SPH\d+|SPC\d+|HP\d+)))$"
        version_regular2 = r"^8.[2-9].(RC\d+|[0-9]|([0-9].(SPH\d+|SPC\d+|HP\d+)))$"
        _, ret_data = self.opr.get_product()
        self.version = ret_data.get("version")
        logger.info("current version is %s" % self.version)
        is_after_813 = True
        if not (re.match(version_regular1, self.version) or re.match(version_regular2, self.version)):
            is_after_813 = False
        return is_after_813

    def do_enable_fsm_sandbox(self, ip_list: list):
        data = self.opr.enable_os_sandbox(ip_list)
        failed_nodes_list = []
        for node in data:
            if node.get('code') != 0:
                failed_nodes_list.append(node)
        if failed_nodes_list:
            err_msg = 'Failed enable sandbox nodes list: %s' % failed_nodes_list
            logger.error(err_msg)
            raise HCCIException(626389, failed_nodes_list)

    def do_disable_fsm_sandbox(self, body):
        data = self.opr.disable_os_sandbox(body)
        failed_nodes_list = []
        for node in data:
            if node.get('code') != 0:
                failed_nodes_list.append(node)
        if failed_nodes_list:
            err_msg = 'Failed disable sandbox nodes list: %s' % failed_nodes_list
            logger.error(err_msg)
            raise HCCIException(626386, failed_nodes_list)


class SandBoxHandlerForDeploy(SandBoxHandlerForUpgrade):
    def setup(self):
        self.fs_args["password"] = self.fs_args.get("dm_update_pwd")
        self.opr.login(DeployConstant.DM_LOGIN_USER, self.fs_args.get("dm_update_pwd"))
        self.is_after_813 = self.storage_version_after_813()
        if not self.is_after_813:
            return
        self.get_fsm_nodes_sandbox_status()
        self.request_body[self.fsm_node[0]] = {'node_ips': [self.fsm_node[0]],
                                               'root_password': self.fs_args.get("fsm_root_pwd"),
                                               'admin_password': self.fs_args.get("dm_update_pwd")}
        self.request_body[self.fsm_node[1]] = {'node_ips': [self.fsm_node[1]],
                                               'root_password': self.fs_args.get("fsm_root_pwd"),
                                               'admin_password': self.fs_args.get("dm_update_pwd")}
