# -*- coding:utf-8 -*-
"""
Function: get_device_info.py moudle. This moudle mainly involves the
Querying Summary Information function.
Copyright: xFusion Digital Technology Co., Ltd. All Rights Reserved (C) 2022-2022
"""
from scripts.common_function import REDFISH_STATUS_CODE_200, UREST_STATUS_CODE_148, RESOURCE

FORMAT = '%-30s: %s'


def getdeviceinfo_init(parser, parser_dict):
    """
    Function Description:initializing the Command for
    Querying Summary Information
    Parameter:parser object: action object
    parser_dict dict: dictionary format of subcommand and ArgumentParser
    """
    sub_parser = parser.add_parser('getdeviceinfo', help='''get devices information''')
    parser_dict['getdeviceinfo'] = sub_parser
    return 'getdeviceinfo'


def getdeviceinfo(client, _):
    """
    Function Description:Querying summary Information
    Parameter:client refishClient: class object
    """
    slotid = client.get_slotid()
    if slotid is None:
        return UREST_STATUS_CODE_148
    summary = {"ibmc": {}, "chassis": {}, "cpu": [], "memory": [],
               "nic": [], "drive": [], "raid": []}
    ibmc_resp = get_ibmc_info(client, slotid, summary)
    get_chassis_info(client, slotid, summary)
    get_processors_info(client, slotid, summary)
    get_memory_info(client, slotid, summary)
    get_nic_info(client, slotid, summary)
    get_drive_info(client, slotid, summary)
    get_raid_info(client, slotid, summary)
    print_result(summary)
    return ibmc_resp


def get_ibmc_info(client, slotid, summary):
    """
    Function Description:Querying ibmc Information
    Parameter: client refishClient: class object
    Parameter: slotid
    Parameter: summary: dict
    """
    ibmc_url = "/redfish/v1/Managers/%s" % slotid
    ibmc_resp = client.get_resource(ibmc_url)
    if ibmc_resp.get("status_code") == REDFISH_STATUS_CODE_200:
        summary["ibmc"]["iBMCVersion"] = ibmc_resp.get("resource").get("FirmwareVersion")
    system_url = "/redfish/v1/Systems/%s" % slotid
    system_resp = client.get_resource(system_url)
    if system_resp.get("status_code") == REDFISH_STATUS_CODE_200:
        resource = system_resp.get(RESOURCE)
        summary["ibmc"]["Serialnumber"] = resource.get("SerialNumber")
        summary["ibmc"]["Manufacturer"] = resource.get("Manufacturer")
        summary["ibmc"]["Devicemodel"] = resource.get("Model")
        summary["ibmc"]["Biosversion"] = resource.get("BiosVersion")
    return ibmc_resp


def get_chassis_info(client, slotid, summary):
    """
    Function Description:Querying chassis Information
    Parameter: client refishClient: class object
    Parameter: slotid
    Parameter: summary: dict
    """
    chassis_url = "/redfish/v1/Chassis/%s" % slotid
    chassis_resp = client.get_resource(chassis_url)
    if chassis_resp.get("status_code") == REDFISH_STATUS_CODE_200:
        resource = chassis_resp.get(RESOURCE)
        summary["chassis"]["ChassisType"] = resource.get("ChassisType")
        summary["chassis"]["Manufacturer"] = resource.get("Manufacturer")
        summary["chassis"]["Model"] = resource.get("Model")
        summary["chassis"]["SerialNumber"] = resource.get("SerialNumber")
        summary["chassis"]["PartNumber"] = resource.get("PartNumber")


def get_processors_info(client, slotid, summary):
    """
    Function Description:Querying Processors Information
    Parameter: client refishClient: class object
    Parameter: slotid
    Parameter: summary: dict
    """
    processors_url = "/redfish/v1/Systems/%s/Processors" % slotid
    processors_resp = client.get_resource(processors_url)
    if processors_resp.get("status_code") != REDFISH_STATUS_CODE_200:
        return
    for member in processors_resp.get("resource").get("Members"):
        url = member.get("@odata.id")
        resp = client.get_resource(url)
        if resp.get("status_code") == REDFISH_STATUS_CODE_200:
            resource = resp.get(RESOURCE)
            processors_info = {
                "Id": resource.get("Id"),
                "ProcessorType": resource.get("ProcessorType"),
                "ProcessorArchitecture": resource.get("ProcessorArchitecture"),
                "InstructionSet": resource.get("InstructionSet"),
                "Manufacturer": resource.get("Manufacturer"),
                "Model": resource.get("Model")
            }
            summary["cpu"].append(processors_info)


def get_memory_info(client, slotid, summary):
    """
    Function Description:Querying memory Information
    Parameter: client refishClient: class object
    Parameter: slotid
    Parameter: summary: dict
    """
    memory_url = "/redfish/v1/Systems/%s/Memory" % slotid
    memory_resp = client.get_resource(memory_url)
    if memory_resp.get("status_code") != REDFISH_STATUS_CODE_200:
        return
    for member in memory_resp.get("resource").get("Members"):
        url = member.get("@odata.id")
        resp = client.get_resource(url)
        if resp.get("status_code") == REDFISH_STATUS_CODE_200:
            resource = resp.get(RESOURCE)
            memory_info = {
                "Id": resource.get("Id"),
                "CapacityMiB": resource.get("CapacityMiB"),
                "Manufacturer": resource.get("Manufacturer"),
                "OperatingSpeedMhz": resource.get("OperatingSpeedMhz"),
                "SerialNumber": resource.get("SerialNumber"),
                "MemoryDeviceType": resource.get("MemoryDeviceType"),
                "PartNumber": resource.get("PartNumber")
            }
            summary["memory"].append(memory_info)


def get_nic_info(client, slotid, summary):
    """
    Function Description:Querying nic Information
    Parameter: client refishClient: class object
    Parameter: slotid
    Parameter: summary: dict
    """
    nic_url = "/redfish/v1/Chassis/%s/NetworkAdapters" % slotid
    nic_resp = client.get_resource(nic_url)
    if nic_resp.get("status_code") != REDFISH_STATUS_CODE_200:
        return
    for member in nic_resp.get("resource").get("Members"):
        url = member.get("@odata.id")
        resp = client.get_resource(url)
        if resp.get("status_code") == REDFISH_STATUS_CODE_200:
            resource = resp.get(RESOURCE)
            nic_info = {
                "Name": resource.get("Name"),
                "Manufacturer": resource.get("Manufacturer"),
                "Model": resource.get("Model"),
            }
            summary["nic"].append(nic_info)


def get_drive_info(client, slotid, summary):
    """
    Function Description:Querying drives Information
    Parameter: client refishClient: class object
    Parameter: slotid
    Parameter: summary: dict
    """
    drive_url = "/redfish/v1/Chassis/%s/Drives" % slotid
    drive_resp = client.get_resource(drive_url)
    if drive_resp.get("status_code") != REDFISH_STATUS_CODE_200:
        return
    for member in drive_resp.get("resource").get("Members"):
        url = member.get("@odata.id")
        resp = client.get_resource(url)
        if resp.get("status_code") == REDFISH_STATUS_CODE_200:
            resource = resp.get(RESOURCE)
            drive_info = {
                "Id": resource.get("Id"),
                "CapacityBytes": resource.get("CapacityBytes"),
                "BlockSizeBytes": resource.get("BlockSizeBytes"),
                "Protocol": resource.get("Protocol"),
                "Manufacturer": resource.get("Manufacturer"),
                "SerialNumber": resource.get("SerialNumber"),
            }
            summary["drive"].append(drive_info)


def get_raid_info(client, slotid, summary):
    """
    Function Description:Querying raid Information
    Parameter: client refishClient: class object
    Parameter: slotid
    Parameter: summary: dict
    """
    storage_url = "/redfish/v1/Systems/%s/Storages" % slotid
    storage_resp = client.get_resource(storage_url)
    if storage_resp.get("status_code") != REDFISH_STATUS_CODE_200:
        return
    for member in storage_resp.get("resource").get("Members"):
        url = member.get("@odata.id")
        resp = client.get_resource(url)
        if resp.get("status_code") == REDFISH_STATUS_CODE_200:
            resource = resp.get(RESOURCE)
            storageController = resource.get("StorageControllers")[0]
            raid_info = {
                "Name": resource.get("Name"),
                "State": storageController.get("Status").get("State"),
                "Health": storageController.get("Status").get("Health"),
                "SpeedGbps": storageController.get("SpeedGbps"),
                "FirmwareVersion": storageController.get("FirmwareVersion"),
                "SupportedDeviceProtocols": storageController.get("SupportedDeviceProtocols"),
                "SerialNumber": storageController.get("SerialNumber"),
                "Manufacturer": storageController.get("Manufacturer"),
                "Model": storageController.get("Model"),
                "TotalCacheSizeMiB": storageController.get("CacheSummary").get("TotalCacheSizeMiB"),
                "SupportedRAIDTypes": storageController.get("SupportedRAIDTypes"),
            }
            summary["raid"].append(raid_info)


def print_result(summary):
    """
    Function Description:print result
    Parameter: summary: info map
    """
    print("-" * 50)
    for key in summary:
        print("[%s]" % key)
        if key in ["ibmc", "chassis"]:
            print("")
            print_info(summary.get(key))
        else:
            for ele in summary.get(key):
                print("")
                print_info(ele)
        print("-" * 50)


def print_info(info):
    """
    Function Description:print result
    Parameter: info: info map
    """
    for info_key in info:
        print(FORMAT % (info_key, info.get(info_key, None)))
