# -*- coding:utf-8 -*-
"""
Function: set_fan.py moudle. This moudle mainly involves the
Setting Fan Information function.
Copyright Information: xFusion Digital Technologies Co.,
 Ltd. All Rights Reserved © 2017-2020
"""
import sys
from scripts.common_function import REDFISH_STATUS_CODE_200
from scripts.common_function import REDFISH_STATUS_CODE_400
from scripts.common_function import REDFISH_STATUS_CODE_404
from scripts.common_function import UREST_STATUS_CODE_144
from scripts import common_function

FAILURE_MESS = 'Failure: some of the settings failed.\
 possible causes include the following: '


def setfan_init(parser, parser_dict):
    """
    Function Description:initializing the Command for
    Setting Fan Information
    Parameter:parser object: action object
    parser_dict dict: dictionary format of subcommand and ArgumentParser
    """
    sub_parser = parser.add_parser('setfan', help='''set fan information''')
    sub_parser.add_argument('-M', dest='FanSpeedAdjustmentMode',
                            type=str, required=False,
                            choices=['Automatic', 'Manual'],
                            help='''fan adjustment mode''')
    sub_parser.add_argument('-SP', dest='FanSpeedLevelPercents',
                            type=int, required=False, help='''fan speed''')
    sub_parser.add_argument('-T', dest='FanManualModeTimeoutSeconds',
                            type=int, required=False,
                            help='duration of fan manual mode')
    parser_dict['setfan'] = sub_parser

    return 'setfan'


def check_err_info(resp, code):
    """
    Function Description:Check error information.
    Parameter:resp dict: redfish interface Value
    code int:redfish interface Code
    """
    # Success flag
    err_message, flag = init_flag(resp)
    if flag == 0:
        print('Success: successfully completed request')
        return resp
    # Determine whether a permission problem occurs.
    if err_message[0]['MessageId'] == \
            "iBMC.1.0.PropertyModificationNeedPrivilege":
        print('Failure: you do not have the required permissions to '
              'perform this operation')
        return None
    # Determine messages according to the returned codes.
    if code == REDFISH_STATUS_CODE_200:
        print_failure_th(err_message)
    if code == REDFISH_STATUS_CODE_400:
        print_failure_fh(err_message)
    return None


def print_failure_fh(err_message):
    """
    Function Description:print error result
    Parameter:err_message list:redfish interface Value
    """
    idx = 0
    # The first message must occupy a single line.
    sys.stdout.write('Failure: ')
    # Poll error information.
    while idx < len(err_message):
        if idx == 0:
            check_info = '%s' % err_message[idx]['Message']
            print(check_info[:len(check_info) - 1].lower())
        else:
            check_info = '         %s' % err_message[idx]['Message']
            print(check_info[:len(check_info) - 1].lower())
        idx += 1


def print_failure_th(err_message):
    """
    Function Description:print error result
    Parameter:err_message list:redfish interface Value
    """
    idx = 0
    print(FAILURE_MESS)
    # Poll error information.
    while idx < len(err_message):
        check_info = '         %s' % err_message[idx]['Message']
        print(check_info[:len(check_info) - 1].lower())
        idx += 1
    sys.exit(UREST_STATUS_CODE_144)


def init_flag(resp):
    """
    Function Description:init flag
    Parameter:resp dict:redfish interface Value
    """
    err_message = ""
    flag = 0
    for key in resp:
        if key == '@Message.ExtendedInfo':
            err_message = resp[key]
            flag = 1
    return err_message, flag


def check_parameter(parser, args):
    """
    Function Description:check CLI command
    Parameter:args object:CLI command
    parser ArgumentParser:subcommand ArgumentParser object
    """
    if args.FanSpeedAdjustmentMode is None and args.FanSpeedLevelPercents \
            is None and args.FanManualModeTimeoutSeconds is None:
        parser.error('at least one parameter must be specified')
    if args.FanSpeedLevelPercents is not None and \
            (args.FanSpeedLevelPercents < 20
             or args.FanSpeedLevelPercents > 100):
        parser.error('argument -SP: invalid choice: %s (choose from 20 to 100)'
                     % args.FanSpeedLevelPercents)
    if args.FanManualModeTimeoutSeconds is not None and \
            (args.FanManualModeTimeoutSeconds < 0
             or args.FanManualModeTimeoutSeconds > 100000000):
        parser.error(
            'argument -T: invalid choice:%s (choose from 0 to 100000000)'
            % args.FanManualModeTimeoutSeconds)
    if (args.FanSpeedAdjustmentMode == 'Automatic') and \
            (args.FanManualModeTimeoutSeconds is not None):
        parser.error('argument -T: if the fan adjustment mode '
                     'is set to auto, the manual adjustment '
                     'duration cannot be set')


def setfan(client, args):
    """
    Function Description:Setting Fan Information
    Parameter:client refishClient: class object
    args object:CLI command
    """
    slotid = client.get_slotid()
    if slotid is None:
        return None
    url = "/redfish/v1/Chassis/%s/Thermal" % slotid

    resp = client.get_resource(url)
    if resp is None:
        return None
    if resp['status_code'] != REDFISH_STATUS_CODE_200:
        if resp['status_code'] == REDFISH_STATUS_CODE_404:
            print('Failure: resource was not found')
        return resp

    payload = init_payload(args)
    # Set attributes.
    resp = client.set_resource(url, payload)
    if resp is None:
        return None
    if resp['status_code'] == REDFISH_STATUS_CODE_200:
        check_err_info(resp['resource'], resp['status_code'])
    if resp['status_code'] == REDFISH_STATUS_CODE_400:
        check_err_info(resp['message']['error'], resp['status_code'])
    return resp


def init_payload(args):
    """
    Function Description:init request parameters
    Parameter:args object:CLI command
    Return Value: payload dict
    """
    # Encapsulate the request body.
    payload = {"Oem": {common_function.COMMON_KEY: {}}}
    payload_vendor = payload['Oem'][common_function.COMMON_KEY]
    if args.FanSpeedAdjustmentMode is not None:
        payload_vendor['FanSpeedAdjustmentMode'] = args.FanSpeedAdjustmentMode
    if args.FanSpeedLevelPercents is not None:
        payload_vendor['FanSpeedLevelPercents'] = args.FanSpeedLevelPercents
    if args.FanManualModeTimeoutSeconds is not None:
        payload_vendor['FanManualModeTimeoutSeconds']\
            = args.FanManualModeTimeoutSeconds
    return payload
