# -*- coding:utf-8 -*-
"""
Function: set_mgmtport.py moudle. This moudle mainly involves the
Setting Information of a Specified iBMC Management Network Port function.
Copyright Information: xFusion Digital Technologies Co.,
 Ltd. All Rights Reserved © 2017-2020
"""
import sys
from scripts.common_function import REDFISH_STATUS_CODE_404
from scripts.common_function import REDFISH_STATUS_CODE_200
from scripts.common_function import REDFISH_STATUS_CODE_400
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 setmgmtport_init(parser, parser_dict):
    """
    Function Description:initializing the Command for
    Setting Information of a Specified iBMC Management Network Port
    Parameter:parser object: action object
    parser_dict dict: dictionary format of subcommand and ArgumentParser
    """
    sub_parser = parser.add_parser('setnetport',
                                   help='''set the management network port''')
    sub_parser.add_argument('-T', dest='Type',
                            type=str, required=False,
                            choices=['Dedicated', 'Aggregation', 'LOM',
                                     'ExternalPCIe', 'LOM2', 'OCP'],
                            help='''network port type''')
    sub_parser.add_argument('-N', dest='PortNumber',
                            type=int, required=False, help='''silkscreen''')
    parser_dict['setnetport'] = sub_parser

    return 'setnetport'


def package_request(args, payload):
    """
    Function Description:Encapsulate the request body.
    Parameter:args object:CLI command
    payload dict:redfish interface Parameter
    """
    oem = {}
    payload_inner_dic = {}
    manager_info = {}
    if args.Type is not None:
        manager_info["Type"] = args.Type
    if args.PortNumber is not None:
        manager_info["PortNumber"] = args.PortNumber
    payload_inner_dic["ManagementNetworkPort"] = manager_info
    oem[common_function.COMMON_KEY] = payload_inner_dic
    payload["Oem"] = oem


def part_err(err_message):
    """
    Function Description:200 messages
    Parameter:ada_message dict:redfish interface value
    """
    idx = 0
    while idx < len(err_message):
        check_info = err_message[idx]['Message']
        message = "%s%s" % \
                  (check_info[0].lower(), check_info[1:len(check_info) - 1])
        message = message.replace("Oem/%s/ManagementNetworkPort"
                                  "/" % common_function.COMMON_KEY, "")
        print('         %s' % message)
        idx += 1


def all_err(err_message):
    """
    Function Description:400 messages
    Parameter:ada_message dict:redfish interface value
    """
    idx = 0
    while idx < len(err_message):
        check_info = err_message[idx]['Message']
        message = "%s%s" % \
                  (check_info[0].lower(), check_info[1:len(check_info) - 1])
        message = message.replace("Oem/%s/ManagementNetworkPort"
                                  "/" % common_function.COMMON_KEY, "")
        if idx == 0:
            print('%s' % message)
        else:
            print('         %s' % message)
        idx += 1


def check_err_info(resp_mgmt, code_mgmt):
    """
    Function Description:Determine whether all attributes are set successfully.
    Parameter:resp_mgmt dict:redfish interface value
    code_mgmt int:redfish interface code
    """
    mess_mgmt = resp_mgmt.get("@Message.ExtendedInfo", "")
    len_mess = len(mess_mgmt)
    if len_mess != 0:
        err_message = resp_mgmt["@Message.ExtendedInfo"]
    else:
        print('Success: successfully completed request')
        return None
    # Determine whether a permission problem occurs.
    if (err_message[0]['MessageId'] ==
            "iBMC.1.0.PropertyModificationNeedPrivilege"
            or err_message[0]['MessageId'] ==
            "Base.1.0.InsufficientPrivilege"):
        print('Failure: you do not have the required permissions to perform '
              'this operation')
        return None
    # Management network port error message
    if code_mgmt == REDFISH_STATUS_CODE_400:
        sys.stdout.write('Failure: ')
        all_err(err_message)
        return None
    # Independent display of 200 messages
    if code_mgmt == REDFISH_STATUS_CODE_200:
        print(FAILURE_MESS)
        part_err(err_message)
        sys.exit(UREST_STATUS_CODE_144)
    return resp_mgmt


def set_managerport_info(members_uri, client, args):
    """
    Function Description:Set network port information.
    Parameter:members_uri str:members uri
    client refishClient: class object
    args object:CLI command
    """
    # Encapsulate the request body.
    payload = {}
    package_request(args, payload)
    resp_mgmt = client.get_resource(members_uri)
    if resp_mgmt is None:
        return None
    if resp_mgmt['status_code'] != REDFISH_STATUS_CODE_200:
        if resp_mgmt['status_code'] == REDFISH_STATUS_CODE_404:
            print('Failure: resource was not found')
        return resp_mgmt
    resp_mgmt = client.set_resource(members_uri, payload)
    if resp_mgmt is None:
        return None
    if resp_mgmt['status_code'] == REDFISH_STATUS_CODE_200:
        check_err_info(resp_mgmt['resource'], resp_mgmt['status_code'])
    if resp_mgmt['status_code'] == REDFISH_STATUS_CODE_404:
        check_err_info(resp_mgmt['message']['error'], resp_mgmt['status_code'])
    if resp_mgmt['status_code'] == REDFISH_STATUS_CODE_400:
        check_err_info(resp_mgmt['message']['error'], resp_mgmt['status_code'])
    return resp_mgmt


def get_port_collection(client, slotid, args):
    """
    Function Description:Query collection information.
    Parameter:client refishClient:class object
    slotid str:manager id
    args object:CLI command
    """
    url = "/redfish/v1/managers/%s/EthernetInterfaces" % slotid
    resp_mgmt = client.get_resource(url)
    if resp_mgmt is None:
        return None
    if resp_mgmt['status_code'] != REDFISH_STATUS_CODE_200:
        if resp_mgmt['status_code'] == REDFISH_STATUS_CODE_404:
            print('Failure: resource was not found')
        return resp_mgmt
    members_count = resp_mgmt['resource']["Members@odata.count"]
    if members_count == 0:
        print("no data available for the resource")
        return resp_mgmt
    # Set information.
    members_uri = resp_mgmt['resource']['Members'][0]["@odata.id"]
    resp_mgmt = set_managerport_info(members_uri, client, args)
    return resp_mgmt


def check_parameter(parser, args):
    """
    Function Description:check CLI command
    Parameter:args object:CLI command
    parser object:subcommand ArgumentParser object
    """
    if args.PortNumber is None and args.Type is None:
        parser.error('at least one parameter must be specified')


def setmgmtport(client, args):
    """
    Function Description:Setting Information of a Specified iBMC
    Management Network Port
    Parameter:client refishClient:class object
    args object:CLI command
    Return Value:ret dict:result of the redfish interface
    """
    slotid = client.get_slotid()
    if slotid is None:
        return None
    # Query collection information.
    ret = get_port_collection(client, slotid, args)
    return ret
