# -*- coding:utf-8 -*-
"""
Function: get_sp_cfg.py moudle. This moudle mainly involves the
 querying the Smart Provisioning Configuration File function.
Copyright Information: xFusion Digital Technologies Co.,
 Ltd. All Rights Reserved © 2020-2021
"""
import sys
from json import dumps
from os import path
from scripts import common_function

FORMAT = '%-30s: %s'
HELP_INFO = 'get SPRAID, SPOSInstallPara, SPCfg information'
FAIL = "Failure: insufficient permission for the file or " \
       "file name not specified, perform this operation as " \
       "system administrator/root, or specify a file name"
ERROR_MESSAGE = {
    "SPOSInstallPara": "os installation and configuration resource ID",
    "SPRAID": "raid configuration file ID",
    "SPCfg": "configuration result resource ID"}


def getspcfg_init(parser, parser_dict):
    """
    Function Description:initializing the Command for querying the
    diagnosis configuration resource information of the
    Smart Provisioning service
    Parameter:parser object: action object
    parser_dict dict: dictionary format of subcommand and ArgumentParser
    Modify: 2020.1.11 delete SPNetDev.
    Return Value: subcommand
    """
    sub_parser = parser.add_parser('getspcfg',
                                   help='''get SP service information''')
    sub_parser.add_argument('-T', dest='type',
                            choices=['SPRAID', 'SPOSInstallPara', 'SPCfg'],
                            required=True, help=HELP_INFO)
    sub_parser.add_argument('-F', dest='file',
                            required=True,
                            help='the loacl path of '
                                 'get the configuration file')
    sub_parser.add_argument('-I', dest='id',
                            required=False,
                            help='%s, %s, or %s' % (
                                ERROR_MESSAGE.get('SPRAID'),
                                ERROR_MESSAGE.get('SPOSInstallPara'),
                                ERROR_MESSAGE.get('SPCfg')))
    parser_dict['getspcfg'] = sub_parser

    return 'getspcfg'


def get_members_id(resp):
    """
    Function Description:get member ids
    Parameter:resp (dict):redfish Interface Value
    Return Value:list:list of member IDs.
    """
    info = resp.get('resource', None)
    if info is None:
        raise common_function.CustomError(common_function.ERROR_MESSAGE)
    members = info.get('Members', None)
    if not members:
        raise common_function.CustomError(common_function.ERROR_MESSAGE)

    return [member.get('@odata.id').split("/")[-1] for member in members if
            member.get('@odata.id') and member.get('@odata.id').split("/")]


def getspcfg(client, args):
    """
    #=====================================================================
    #   @Method: SP query subcommand processing functions
    #   @Param:  client, RedfishClient object
                 args, parameter list
    #   @Return:
    #   @author:
    #   @date:  2017-11-14 09:04:14
    #=====================================================================
    """
    slotid = client.get_slotid()
    if slotid is None:
        return None

    url = "/redfish/v1/Managers/%s/SPService/%s" % (slotid, args.type)
    resp = client.get_resource(url)
    if resp is None or resp.get("status_code", None) is None:
        print(common_function.ERROR_MESSAGE)
        return None

    if resp['status_code'] == 200:
        try:
            member_ids = get_members_id(resp)
        except common_function.CustomError as e:
            print(e)
            return resp

        if not member_ids:
            print("no available %s" % ERROR_MESSAGE.get(args.type))
        else:
            exit_message = "Failure: The value of parameter" \
                           " I must be set to {%s}." % ','.join(member_ids)
            if not args.id or args.id not in member_ids:
                print(exit_message)
                sys.exit(common_function.UREST_STATUS_CODE_2)

            resp = print_resource(client, args, url)
    elif resp['status_code'] == 404:
        print('Failure: resource was not found')
    elif resp['status_code'] == 500:
        print("Failure: the request failed due to an internal service error")

    return resp


def print_resource(client, args, url):
    """
    #=====================================================================
    #   @Method:  Display specified SP data.
    #   @Param:   info, SP message dictionary
    #             args, command parameter
    #   @Return:
    #   @author:
    #=====================================================================
    """
    sub_resp = None
    if args is not None:
        # Display data specified by parameters.
        sub_url = url + "/%s" % args.id
        sub_resp = client.get_resource(sub_url)
        sub_info = sub_resp.get('resource', None)
        if sub_info is None:
            print(common_function.ERROR_MESSAGE)
            return None
        del sub_info["@odata.context"]
        del sub_info["@odata.id"]
        del sub_info["@odata.type"]
        if sub_info.get('Actions', None) is not None:
            del sub_info['Actions']
        del sub_info['Name']
        if args.type != 'SPRAID':
            del sub_info['Id']
        len_info = len(sub_info)

        if len_info == 0:
            print(common_function.ERROR_MESSAGE)
            return sub_resp

        if args.file is not None:
            if creat_res_file(args.file, sub_info) is True:
                print('Success: successfully completed request')
            else:
                return None
        else:
            print_info(sub_info)

    return sub_resp


def creat_res_file(file_path, dict_info):
    """
    #=====================================================================
    #   @Method:  Export JSON files.
    #   @Param:   info, SP message dictionary
    #             args, command function parameter
    #   @Return:
    #   @author:
    #=====================================================================
    """
    # Check the path.
    file_dir = path.dirname(file_path)
    if path.exists(file_dir) is not True:
        print("Failure: the path does not exist")
        return False

    if path.isdir(file_path) is True:
        print("Failure: please specify a file name")
        return False
    try:
        json_obj = dumps(dict_info)
        common_function.write_file(file_path=file_path, file_content=json_obj)
    except OSError:
        print(FAIL)
        return False

    return True


def print_info(info):
    """
    #=====================================================================
    #   @Method:  print result
    #   @Param:   info，resource
    #
    #   @Return:
    #   @author:
    #=====================================================================
    """
    return info
