#!/usr/bin/python
# -*- coding: UTF-8 -*-
"""
Function: get_processor.py moudle. This moudle mainly involves the querying
 information about the specified processor resource of a server function.
Copyright Information: xFusion Digital Technologies Co., Ltd. All Rights Reserved © 2021
"""
from scripts.common_function import UniqueStore
from scripts.common_function import CustomError
from scripts import common_function

PRO_FORMAT = '%-25s: %s'

CPU = "CPU"
NPU = "NPU"
TITLE_KEY = ["IPv4Address", "IPv6Address"]
TITLE_DICT = {"Status": None, "ProcessorId": None, "MemoryOnChip": None,
              "EthernetInterface": None}


def get_processor_init(parser, parser_dict):
    """
    Function Description:initializing the Command for
    Query information about the specified processor resource of a server.
    Parameter:parser object: action object
    parser_dict dict: dictionary format of subcommand and ArgumentParser
    """
    sub_parser = parser.add_parser('getprocessor',
                                   help='query information about the'
                                        ' specified processor resource'
                                        ' of a server')
    sub_parser.add_argument('-T', dest='processor_type',
                            choices=[CPU, NPU],
                            action=UniqueStore,
                            required=True,
                            help='type of the specified processor')
    parser_dict['getprocessor'] = sub_parser

    return 'getprocessor'


def print_info(specify_processor_resource, title_value_dict=None):
    """
    Function Description:print specify processor
    Parameter:specify_processor_resource dict: redfish Interface Value
              title_value_dict dict:title value
    """
    print('-' * 50)
    print_key_value(specify_processor_resource, title_value_dict)
    if title_value_dict:
        for key, value in title_value_dict.items():
            if not value:
                continue

            print("\n[%s]" % key)
            print_key_value(value, title_value_dict)


def print_key_value(resource, title_value_dict=None):
    """
    Function Description:print info
    Parameter:resource dict: redfish Interface Value
              title_value_dict dict:title value
    """
    if title_value_dict is None:
        title_value_dict = {}

    for key, value in resource.items():
        if str(key).startswith("@"):
            continue
        if key in title_value_dict:
            title_value_dict[key] = value
        elif isinstance(value, dict):
            if key in TITLE_KEY:
                print("%s:" % key)
            print_key_value(value, title_value_dict)
        else:
            print(PRO_FORMAT % (key, value))


def print_processor(informations, args=None):
    """
    Function Description:print information about the
                         specified processor resource of a server
    Parameter:informations list: specifies the information set for the processor
              args object: CLI command
    """
    for specify_processor_resource in informations:
        if args.processor_type == CPU:
            print_info(specify_processor_resource,
                       title_value_dict={"Status": None, "ProcessorId": None})
        else:
            print_info(specify_processor_resource,
                       title_value_dict={"Status": None,
                                         "ProcessorId": None,
                                         "MemoryOnChip": None,
                                         "EthernetInterface": None})

    print('-' * 50)


def check_result(request_result):
    """
    Function Description:check result
    Parameter:request_result dict: request result
    """
    if not request_result:
        raise CustomError(common_function.RESOURCE_NULL)

    if request_result['status_code'] != 200:
        raise CustomError(request_result)


def print_processor_summary(client, args, slotid, count):
    """
    Function Description:Query system resource CPU information.
    Parameter:client refishClient: class object
              args object:CLI Command
              slotid str:ID of a system resource.
              count int:number of Non-CPU Processors
    """
    if args.processor_type != CPU:
        print('-' * 50)
        print(PRO_FORMAT % ('Count', count))
        return

    url = "/redfish/v1/Systems/%s/" % slotid
    sys_resp = client.get_resource(url)

    print_info(sys_resp['resource']['ProcessorSummary'],
               title_value_dict={'Status': None})


def get_processor_information(client, args, slotid):
    """
    Function Description:get processor count
    Parameter:client refishClient: class object
              args object:CLI command
              slotid str:ID of a system resource.
    """
    informations = []
    url = "/redfish/v1/Systems/%s/Processors/" % slotid
    collection_resp = client.get_resource(url)
    check_result(collection_resp)

    count = collection_resp['resource'].get('Members@odata.count', {})
    count = count if count else 0

    for i in range(0, count):
        data_id = collection_resp['resource'].get('Members', {})[i].get('@odata.id', '')
        processor_info = client.get_resource(data_id)
        check_result(processor_info)

        if processor_info['resource'].get('ProcessorType', '') == args.processor_type:
            informations.append(processor_info['resource'])

    return tuple(informations)


def get_processor(client, args):
    """
    Function Description:Querying information about the
                         specified processor resource of a server
    Parameter:client refishClient: class object
              parser object: action object
              args object:CLI command
    """
    slotid = client.get_slotid()
    if slotid is None:
        raise CustomError(common_function.SLOT_ID_ERROR)

    informations = get_processor_information(client, args, slotid)
    print_processor_summary(client, args, slotid, len(informations))
    if len(informations) == 0:
        print('-' * 50)
        return {'status_code': 200}

    print_processor(informations, args)
    return informations[-1]
