# -*- coding: utf-8 -*-
"""
Storage参数校验
"""
import traceback

import utils.common.log as logger
from utils.business.project_util import ProjectApi
from utils.business.param_util import HandleParamCheck
from utils.business.param_util import ParamUtil as ParamService
from utils.business.vm_util import can_vm_pinged_to
from utils.common.exception import HCCIException
from utils.business.project_condition_utils import get_project_condition_boolean
from plugins.DistributedStorage.common.UpgradeOperate import UpgradeOperate
from plugins.DistributedStorage.common.RestClient import StorageSSHClient


def params_check(project_id):
    check_result = HandleParamCheck()
    check_list = []
    try:
        """参数检验"""
        logger.info('Start parameter verification task.')
        service_name = "DistributedStorage"
        suit_info = ProjectApi().get_storage80_info(project_id)
        check_data = ParamService().get_need_check_cloud_params(project_id,
                                                                service_name)
        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]

            _check_rest_connectivity(check_list, check_data, check_result,
                                     suit_id, float_ip)
        if get_project_condition_boolean(project_id, "InstalledCSHA&IsTenantStorFB80"):
            check_arb_connectivity(check_result, check_data)

    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)))
    return check_result


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 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_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 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:
    """
    try:
        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)
        status_code, error_code, error_des = operator.login(
            fs_args['user_name'], fs_args['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)

    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
