# -*- coding:utf-8 -*-
"""
Function: set_adaptiveport.py moudle. This moudle mainly involves the
Setting the iBMC Self-Adaptation Network Port Information 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 setadaptiveport_init(parser, parser_dict):
    """
    Function Description:initializing the Command for
    Setting the iBMC Self-Adaptation Network Port Information
    Parameter:parser object: action object
    parser_dict dict: dictionary format of subcommand and ArgumentParser
    """
    sub_parser = parser.add_parser('setadaptiveport',
                                   help='''set self-adaptive port''')
    sub_parser.add_argument('-T', dest='Type',
                            type=str, required=True,
                            choices=['Dedicated', 'Aggregation', 'LOM',
                                     'ExternalPCIe', 'LOM2', 'OCP', 'OCP2', 'OCP3'],
                            help='''network port type''')
    sub_parser.add_argument('-N', dest='PortNumber',
                            type=int, required=True, help='''silkscreen''')
    sub_parser.add_argument('-F', dest='AdaptiveFlag',
                            type=str, choices=['True', 'False'], required=True,
                            help='''autonegotiation flag''')
    parser_dict['setadaptiveport'] = sub_parser

    return 'setadaptiveport'


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 = {}
    adaptive_info = {}
    if args.Type is not None:
        adaptive_info["Type"] = args.Type
    if args.PortNumber is not None:
        adaptive_info["PortNumber"] = args.PortNumber
    if args.AdaptiveFlag is not None:
        adaptive_info["AdaptiveFlag"] = args.AdaptiveFlag == str(True)
    payload_inner_dic["AdaptivePort"] = [adaptive_info]
    oem[common_function.COMMON_KEY] = payload_inner_dic
    payload["Oem"] = oem


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


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


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

    return resp_ada


def set_adaptiveport_info(members_uri, client, args):
    """
    Function Description:Set adaptive 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_ada = client.get_resource(members_uri)
    if resp_ada is None:
        return None
    if resp_ada['status_code'] != REDFISH_STATUS_CODE_200:
        if resp_ada['status_code'] == REDFISH_STATUS_CODE_404:
            print('Failure: resource was not found')
        return resp_ada
    resp_ada = client.set_resource(members_uri, payload)
    if resp_ada is None:
        return None

    if resp_ada['status_code'] == REDFISH_STATUS_CODE_200:
        check_err_info(resp_ada['resource'], resp_ada['status_code'])

    if resp_ada['status_code'] == REDFISH_STATUS_CODE_400:
        check_err_info(resp_ada['message']['error'], resp_ada['status_code'])

    return resp_ada


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_ada = client.get_resource(url)
    if resp_ada is None:
        return None
    if resp_ada['status_code'] != REDFISH_STATUS_CODE_200:
        if resp_ada['status_code'] == REDFISH_STATUS_CODE_404:
            print('Failure: resource was not found')
        return resp_ada
    members_count = resp_ada['resource']["Members@odata.count"]
    if members_count == 0:
        print("no data available for the resource")
        return resp_ada
    # Set information.
    members_uri = resp_ada['resource']['Members'][0]["@odata.id"]
    resp_ada = set_adaptiveport_info(members_uri, client, args)

    return resp_ada


def setadaptiveport(client, args):
    """
    Function Description:Setting the iBMC Self-Adaptation
    Network Port Information
    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
