# -*- coding:utf-8 -*-
"""
Function: set_vnc.py moudle. This moudle mainly involves the
 setting VNC Information function.
Copyright Information: xFusion Digital Technologies Co.,
 Ltd. All Rights Reserved © 2020-2021
"""
import sys
from scripts import common_function

FAILURE_MESS = 'Failure: some of the settings failed.\
 possible causes include the following: '
password = None


def setvnc_init(parser, parser_list):
    """
    #=====================================================================
    #   @Method:Register command functions
    #   @Param:
    #   @Return:
    #   @author:
    #=====================================================================
    """
    sub_parser = parser.add_parser('setvnc', help='''set VNC information''')
    sub_parser.add_argument('-S', dest='SSLEncryptionEnabled',
                            type=str, required=False,
                            choices=['False', 'True'],
                            help='''SSL encryption''')
    sub_parser.add_argument('-K', dest='KeyboardLayout',
                            type=str, required=False, choices=['en', 'jp'],
                            help='''keyboard layout''')
    sub_parser.add_argument('-to', dest='Timeout',
                            type=int, required=False,
                            help='''timeout period (min)''')
    sub_parser.add_argument('-P', dest='Password',
                            type=str, required=False,
                            default=None,
                            help='''password''')
    sub_parser.add_argument('-E', dest='VNCPasswordEnable',
                            type=str, required=False,
                            choices=["True", "False"],
                            default="False",
                            help='specifies whether to enable the'
                                 ' VNC password setting function.'
                                 ' the default value is False')
    sub_parser.add_argument('-R', dest='LoginRule',
                            type=str, required=False, nargs='*',
                            choices=['Rule1', 'Rule2', 'Rule3'],
                            help='''login rule, example: -R Rule1 Rule3''')
    parser_list['setvnc'] = sub_parser

    return 'setvnc'


def check_parameter(parser, args):
    """
    Function Description:check CLI command
    Parameter:args object:CLI command
    parser object:subcommand ArgumentParser object
    """
    if args.Password is not None and args.VNCPasswordEnable == 'True':
        parser.error('-E is not needed in non-interactive command')
    if args.VNCPasswordEnable == "False" and common_function.all_none(
            args.SSLEncryptionEnabled, args.KeyboardLayout,
            args.Timeout,
            args.Password,
            args.LoginRule):
        parser.error(
            'at least one parameter of -S,-K,-to,-P and -R must be specified')
    if args.Timeout is not None and (args.Timeout < 0 or args.Timeout > 480):
        parser.error('argument -to: invalid choice'
                     ': %d (choose from 0 to 480)' % args.Timeout)
    if args.LoginRule is not None:
        idx = 0
        # Process invalid values
        while idx < len(args.LoginRule):
            # Duplication check
            if args.LoginRule.count(args.LoginRule[idx]) > 1:
                parser.error('argument -R: '
                             'Repeat values: \'%s\'' % args.LoginRule[idx])
            idx += 1


def setvnc(client, args):
    """
    #=====================================================================
    #   @Method:Command processing function
    #   @Param:
    #   @Return:
    #   @author:
    #=====================================================================
    """
    global password
    if args.Password is not None:
        password = args.Password
    elif args.VNCPasswordEnable == "True":
        password = common_function.subcommand_pwd("VNC", False)
    slotid = client.get_slotid()
    if slotid is None:
        return None
    url = "/redfish/v1/managers/%s/VNCservice" % slotid
    resp_vnc = client.get_resource(url)
    if resp_vnc is None:
        return None
    if resp_vnc['status_code'] == 200:
        # Set attributes
        resp_vnc = set_vncinfo(url, client, args)
    if resp_vnc['status_code'] == 404:
        print('Failure: resource was not found')

    return resp_vnc


def set_vncinfo(url, client, args):
    """
    #=====================================================================
    #   @Method:Set resource information
    #   @Param:
    #   @Return:
    #   @author:
    #=====================================================================
    """
    ret = package_request(args)
    # Set vnc  resource attributes
    resp_vnc = client.set_resource(url, ret)
    if resp_vnc is None:
        return None
    if resp_vnc['status_code'] == 200:
        flag = check_err_info(resp_vnc['resource'], resp_vnc['status_code'])
        if not flag:
            sys.exit(144)
    if resp_vnc['status_code'] == 400:
        check_err_info(resp_vnc['message']['error'], resp_vnc['status_code'])
    return resp_vnc


def check_err_info(resp_vnc, code_vnc):
    """
    #==========================================================================
    # @Method: Determine whether all attributes are set successfully.
     Query @Message.ExtendedInfo
    # @Param:resp_vnc
    # @date:2017.08.13 12:07
    # @author:
    #==========================================================================
    """
    flag = False
    vnc_mess = resp_vnc.get("@Message.ExtendedInfo", "")
    # Determine whether the configuration is successful
    if vnc_mess == "":
        print('Success: successfully completed request')
        flag = True
    else:
        # Determine whether a permission problem occurs.
        #  There is only one type of permission on the entire resource
        mess_id = vnc_mess[0].get("MessageId", "")
        if mess_id in ["iBMC.1.0.PropertyModificationNeedPrivilege",
                       "Base.1.0.InsufficientPrivilege"]:
            print('Failure: you do not have the required permissions to '
                  'perform this operation')
        else:
            # Display messages
            resq_mess(vnc_mess, code_vnc)
    return flag


def resq_mess(vnc_mess, code_vnc):
    """
    #==========================================================================
    # @Method: Respond to messages
    # @Param:idx, err_message， code_vnc
    # @Return:
    # @author:
    #==========================================================================
    """
    if code_vnc == 200:
        print(FAILURE_MESS)
    else:
        sys.stdout.write('Failure: ')
    idx = 0
    while idx < len(vnc_mess):
        message = vnc_mess[idx].get('Message', "")
        # Display messages
        message = "%s%s" % (message[0].lower(), message[1:len(message) - 1])
        message = message.replace("Oem/%s/" % common_function.COMMON_KEY, "")

        if code_vnc == 400 and idx == 0:
            print('%s' % message)
        else:
            print('         %s' % message)
        idx += 1


def package_request(args):
    """
    #=====================================================================
    #   @Method:Encapsulate the request body
    #   @Param:
    #   @date:2017.08.29 09:12
    #   @author:
    #=====================================================================
    """
    payload = {}
    if args.SSLEncryptionEnabled is not None:
        payload["SSLEncryptionEnabled"] = args.SSLEncryptionEnabled == str(
            True)
    if args.KeyboardLayout is not None:
        payload["KeyboardLayout"] = args.KeyboardLayout
    if args.Timeout is not None:
        payload["SessionTimeoutMinutes"] = args.Timeout
    if password is not None:
        payload["Password"] = password
    if args.LoginRule is not None:
        payload["LoginRule"] = args.LoginRule
    return payload
