# -*- coding: utf-8 -*-
# Copyright (c) Huawei Technologies Co., Ltd. 2022-2023. All rights reserved.
"""
Storage参数校验
"""
import traceback
import utils.common.log as logger
from utils.business.param_util import HandleParamCheck
from utils.business.param_util import ParamUtil as ParamService
from utils.business.project_util import ProjectService
from utils.business.vm_util import can_vm_pinged_to
from utils.common.exception import HCCIException
from utils.business.project_util import ProjectApi
from utils.business.project_condition_utils import get_project_condition_boolean
from plugins.DistributedStorage.common.upgrade_operate import UpgradeOperate
from plugins.DistributedStorage.common.rest_client import StorageSSHClient


def params_check(project_id):
    check_result = HandleParamCheck()
    check_list = []
    """参数检验"""
    logger.info('Start parameter verification task.')
    service_name = "DistributedStorage"
    check_data = None
    project_info = None
    suit_info = None
    try:
        check_data, project_info, suit_info = _get_check_params(project_id, service_name)
    except HCCIException as err:
        exc = traceback.format_exc()
        logger.error('param check failed.%s' % (str(exc)))
        check_result.set_check_result(param_keys=check_list, status=500, error_msg=err)
    except Exception as ex:
        logger.error(ex)
        exc = traceback.format_exc()
        logger.error('param check failed.%s' % (str(exc)))
        check_result.set_check_result(param_keys=check_list, status=500, error_msg=HCCIException(620050, str(ex)))
    for suit_id, float_ip in suit_info.items():
        logger.info("check {} begin".format(suit_id))

        rest_check_list = ['FSM_{}_float_ip', 'FSM_{}_rest_user',
                           'FSM_{}_rest_pwd']
        check_list = [str(i).format(suit_id) for i in rest_check_list]
        try:
            _check_rest_connectivity(check_list, check_data, check_result, suit_id, float_ip)
        except HCCIException as err:
            exc = traceback.format_exc()
            logger.error('param check failed.%s' % (str(exc)))
            check_result.set_check_result(param_keys=check_list, status=500, error_msg=err)
        except Exception as ex:
            logger.error(ex)
            exc = traceback.format_exc()
            logger.error('param check failed.%s' % (str(exc)))
            check_result.set_check_result(param_keys=check_list, status=500, error_msg=HCCIException(620050, str(ex)))
    if get_project_condition_boolean(project_id, "InstalledCSHA&IsTenantStorFB80"):
        check_arb_connectivity(check_result, check_data)

    return check_result


def _get_check_params(project_id, service_name):
    suit_info = ProjectApi().get_storage80_info(project_id)
    check_data = ParamService().get_need_check_cloud_params(project_id, service_name)
    project_info = ProjectService().get_project_info(project_id)
    return check_data, project_info, suit_info


def _check_rest_connectivity(check_list, check_data, check_result, suit_id, float_ip):
    data_dict = get_check_item(check_list, check_data, check_result)
    if len(data_dict) == 0:
        return
    check_float_ip = data_dict.get(check_list[0])
    if check_float_ip != float_ip:

        check_result.set_check_result(
            check_list, 500,
            HCCIException(621012, suit_id, float_ip, check_float_ip))
    else:
        if not check_ping(check_list, check_result, data_dict):
            return
        if check_rest_connectivity(check_list, data_dict,
                                   check_result):
            check_result.set_check_result(
                param_keys=check_list, status=200)


def check_arb_connectivity(check_result, check_data):
    logger.info("Check quorum server connectivity")
    check_list = ["QuorumServerIP", "QuorumServerPwd"]
    data_dict = get_check_item(check_list, check_data, check_result)
    server_ip = data_dict.get("QuorumServerIP")
    root_pwd = data_dict.get("QuorumServerPwd")
    if not check_ping(check_list, check_result, data_dict):
        return
    try:
        ssh_client = StorageSSHClient(server_ip, 'root', root_pwd)
    except Exception as err:
        err_msg = "ssh {0} with {1} failed. exc {2}".format(
            server_ip, "root", err)
        check_result.set_check_result(param_keys=check_list,
                                      status=500,
                                      error_msg=HCCIException(621019, err_msg))


def get_check_item(check_list, check_data, check_result):
    data_dict = {}
    error = []
    for key, val in check_data.items():
        if key in check_list and val:
            data_dict.update({key: val})
        elif key in check_list and not val:
            error.append(key)
    if error:
        logger.error("check key {} error".format(', '.join(error)))
        check_result.set_check_result(check_list,
                                      500,
                                      HCCIException(620053, ', '.join(error)))
        return {}
    return data_dict


def check_ping(check_list, check_result, data_dict):
    check_pass_flag = True
    ip_addr = data_dict.get(check_list[0])
    result = can_vm_pinged_to(ip_addr)
    if not result:
        logger.error("IP({}) is unreachable.".format(ip_addr))
        logger.error("check ping ip {ip_list} error, "
                     "error: {result}".format(ip_list=ip_addr,
                                              result=result))
        check_result.set_check_result(check_list,
                                      500,
                                      HCCIException(620054, ip_addr))
        check_pass_flag = False
    return check_pass_flag


def check_rest_connectivity(check_list, data_dict, check_result):
    """
    :param data_dict:
    :param check_result:
    :param check_list:
    :return:
    """
    check_pass_flag = True
    # 组合请求数据
    logger.info('Start collecting request data.')
    fs_args = dict()
    fs_args['float_ip'] = data_dict.get(check_list[0])
    fs_args['user_name'] = data_dict.get(check_list[1])
    fs_args['password'] = data_dict.get(check_list[2])
    fs_args['port'] = "8088"
    operator = UpgradeOperate(fs_args)
    try:
        do_check_rest_connectivity(fs_args, operator)
    except HCCIException as err:
        logger.error(err)
        logger.error(traceback.format_exc())
        check_result.set_check_result(param_keys=check_list, status=500, error_msg=err)
        check_pass_flag = False
    except Exception as ex:
        logger.error(ex)
        logger.error(traceback.format_exc())
        check_result.set_check_result(param_keys=check_list, status=500, error_msg=HCCIException(620050, str(ex)))
        check_pass_flag = False
    finally:
        logger.info('check_rest_connectivity end.')

    return check_pass_flag


def do_check_rest_connectivity(fs_args, operator):
    status_code, error_code, error_des = operator.login(fs_args.get('user_name'), fs_args.get('password'))
    if status_code != 200 or error_code != 0:
        err_msg = "Failed to login, Detail:[status:%s,code:%s]%s" \
                  % (status_code, error_code, error_des)
        logger.error(err_msg)
        raise Exception(err_msg)
    ret_result, ret_data = operator.logout()
    if ret_result["code"] != 0:
        err_msg = "Failed to logout, Detail:[{0}, {1}]".format(ret_result, ret_data)
        logger.error(err_msg)
        raise Exception(err_msg)

