# -*- coding:utf-8 -*-
"""
Function: set_user_password.py moudle. This moudle mainly involves the
Setting a User Password function.
Copyright Information: xFusion Digital Technologies Co.,
 Ltd. All Rights Reserved © 2017-2020
"""
import sys
from scripts import common_function


def setuserpassword_init(parser, parser_dict):
    """
    Function Description:initializing the Command for
    Setting a User Password
    Parameter:parser object: action object
    parser_dict dict: dictionary format of subcommand and ArgumentParser
    """
    sub_parser = parser.add_parser('setpwd',
                                   help='''set password''')
    sub_parser.add_argument('-N',
                            dest='name',
                            required=False,
                            help='user name. specify the user to be modified. '
                                 'if no user is specified, the command modifies'
                                 ' information about the current login user')
    sub_parser.add_argument('-P',
                            dest='newpassword',
                            required=False,
                            default=None,
                            help='''new password''')
    sub_parser.add_argument('-E', dest='UserPasswordEnable',
                            type=str, required=False,
                            choices=['True', 'False'],
                            default='False',
                            help='specifies whether to enable the user'
                                 ' password setting function.'
                                 ' the default value is False')
    sub_parser.add_argument('-AP', dest='prompt',
                            type=str, required=False,
                            help='account insecure prompt enabled ',
                            choices=['True', 'False'])

    parser_dict['setpwd'] = sub_parser

    return 'setpwd'


def setuserpassword(client, args):
    """
    Function Description:Setting a User Password
    Parameter:client refishClient: class object
    args object:CLI command
    """
    username, password = init_name_password(args)
    payload = init_payload(args, password)
    url = "/redfish/v1/AccountService/Accounts"

    resp = client.get_resource(url)
    if resp is None:
        return resp
    if resp['status_code'] != common_function.REDFISH_STATUS_CODE_200:
        error_message(resp)
        return resp
    resp = setuserpassword_info(client, resp, username, payload)
    return resp


def init_name_password(args):
    """
    Function Description:init User Name and User Password
    Parameter:args object:CLI command
    """
    password = None
    username = args.username
    if args.name is not None:
        username = args.name
    if args.newpassword is not None:
        password = args.newpassword
    elif args.UserPasswordEnable == "True":
        password = common_function.subcommand_pwd(username, False)
    return username, password


def init_payload(args, password):
    """
    Function Description:init payload
    Parameter:args object:CLI command
    password str:user password
    """
    prompt_enabled = {}
    payload = {}
    if args.prompt is not None:
        prompt_enabled['AccountInsecurePromptEnabled'] = \
            common_function.stringtobool(args.prompt)
        if password is not None:
            payload = {"Password": password,
                       "Oem": {common_function.COMMON_KEY: prompt_enabled}}
        else:
            payload = {"Oem": {common_function.COMMON_KEY: prompt_enabled}}
    elif password is not None:
        payload = {"Password": password}
    return payload


def check_resp(messages):
    """
    Function Description:Process some success messages.
    Parameter:messages list:redfish interface value
    """
    err_format = '{0}{1}'
    print("Failure: some of the settings failed. possible causes "
          "include the following: ")
    length = len(messages)
    index = 0
    while index < length:
        message = messages[index]['Message']
        check_info = message.replace("Oem/%s/" % common_function.COMMON_KEY,
                                     "")
        message = "%s%s" % \
                  (check_info[0].lower(), check_info[1:len(check_info) - 1])
        print(err_format.format('         ', message))
        index += 1


def setuserpassword_info(client, resp, username, payload):
    """
    Function Description:set user password
    Parameter:client refishClient: class object
    resp dict:redfish interface value
    username str:user name
    payload dict:redfish interface Parameter
    """
    for user_id in resp['resource']['Members']:
        url = user_id['@odata.id']
        user_resp = client.get_resource(url)
        if user_resp is None:
            return None

        if user_resp['status_code'] != common_function.REDFISH_STATUS_CODE_200:
            error_message(user_resp)
            return user_resp

        if username == user_resp['resource']['UserName']:
            set_resp = client.set_resource(url, payload)
            if resp is None:
                return None

            if set_resp['status_code'] \
                    == common_function.REDFISH_STATUS_CODE_200:
                print_set_result(set_resp)
                return set_resp

            error_message(set_resp)
            return set_resp
    message_dict = {"status_code": common_function.REDFISH_STATUS_CODE_404,
                    "message": 'Failure: the user does not exist'}
    print(message_dict.get("message"))
    return message_dict


def print_set_result(set_resp):
    """
    Function Description:print result
    Parameter:set_resp dict:redfish interface value
    """
    if set_resp['resource'].get(
            '@Message.ExtendedInfo') is not None:
        messages = set_resp['resource']['@Message.ExtendedInfo']
        check_resp(messages)
        sys.exit(common_function.UREST_STATUS_CODE_144)
    else:
        print('Success: successfully completed request')


def error_message(resp):
    """
    Function Description:print error message
    Parameter:resp dict:redfish interface value
    """
    message = resp['message']['error']['@Message.ExtendedInfo']
    message_info = common_function.change_message(message[0]['Message'])
    error_message_dict = {
        'InvalidPasswordSameWithHistory':
            'Failure: failed to set the user password, '
            'a valid password cannot be limited history password',
        'InvalidPassword':
            'Failure: failed to set the user password, '
            'the password is invalid because it is empty',
        'PasswordNotSatisfyComplexity':
            'Failure: the password does not meet '
            'password complexity requirements'
    }
    if resp['status_code'] == common_function.REDFISH_STATUS_CODE_404:
        print("Failure: resource was not found")
    elif resp['status_code'] == common_function.REDFISH_STATUS_CODE_400:
        messageid = message[0]['MessageId'].split('.')[-1]
        if messageid in error_message_dict:
            print(error_message_dict.get(messageid))
        else:
            print("Failure: %s" % message_info)
    else:
        print("Failure: the request failed due to an internal service error")


def check_parameter(parser, args):
    """
    Function Description:check CLI command
    Parameter:args object:CLI command
    parser ArgumentParser:subcommand ArgumentParser object
    """
    if args.newpassword is not None and args.UserPasswordEnable == 'True':
        parser.error('-E is not needed in non-interactive command')
    if args.UserPasswordEnable == "False" and args.newpassword is None and args.prompt is None:
        parser.error('-AP parameters must be specified.')
