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


def importsslcert_init(parser, parser_dict):
    """
    Function Description:import SSL certificate subcommand init
    Parameter:parser object: action object
    parser_dict dict: dictionary format of subcommand and ArgumentParser
    Modify: The -F parameter is added.
            2019.4.28 The help information is optimized.
    Return Value: subcommand
    """
    sub_parser = parser.add_parser('importsslcert',
                                   help='''import SSL certificate''')

    sub_parser.add_argument('-T', dest='Type',
                            required=True, choices={'server', 'custom'},
                            help='''the type of certificate''')

    sub_parser.add_argument('-C', dest='Content',
                            type=str, required=False, default=None,
                            help='path of the SSL certificate.'
                                 ' On a local file server, the'
                                 ' certificate can be stored only'
                                 ' in the /tmp directory of iBMC,'
                                 ' and the path format is'
                                 ' /tmp/file name. On a remote file'
                                 ' server, the path format is protocol://'
                                 'User name:Password@IP address/'
                                 'Folder/File name. The file '
                                 'transfer protocols include the'
                                 ' following: sftp, https, nfs,' 
                                 ' cifs, scp.')

    sub_parser.add_argument('-F', dest='file', required=False,
                            help='the path of file. Local '
                                 'import:Folder/File name.\n\r')

    sub_parser.add_argument('-P', dest='CertPassword',
                            required=False, default=None,
                            help='the password of '
                                 'custom encrypted certificate')

    sub_parser.add_argument('-E', dest='CertPasswordEnable',
                            type=str, required=False,
                            choices=["True", "False"],
                            default="False",
                            help='specifies whether to enable the'
                                 ' SSL certificate password.'
                                 ' the default value is False')

    image_uri = {common_function.REQUIRED_FLAG: False,
                 common_function.HELP_INFO: 'path of the SSL certificate.'
                                            ' On a local file server, the'
                                            ' certificate can be stored only'
                                            ' in the /tmp directory of iBMC,'
                                            ' and the path format is'
                                            ' /tmp/file name. On a remote file'
                                            ' server, the path format is server'
                                            ' IP address/directory/file name.'}
    args_pro = {common_function.REQUIRED_FLAG: False}
    args_acc = {common_function.REQUIRED_FLAG: False}
    common_function.unpack_remote_server_path(sub_parser, image_uri,
                                              args_pro, args_acc)

    parser_dict['importsslcert'] = sub_parser

    return 'importsslcert'


def _resptaskparse(resp, client):
    """
    #====================================================================
    #   @Description:  parse response code and body
    #
    #   @Date: 2017.08.31 09:10
    #====================================================================
    """

    taskid = resp['resource']['@odata.id']

    ssl_resp = client.get_resource(taskid)
    if ssl_resp is None:
        sys.exit(127)

    if ssl_resp['status_code'] != 200:
        message = (ssl_resp['message']['error']['@Message.ExtendedInfo'][0][
            'Message']).lower()
        print('Failure: ' + message[:-1])
    else:
        message = (ssl_resp['resource']['Messages']['Message']).lower()
        print('Failure: ' + message[:-1])


def _respparse(resp):
    """
    #=====================================================================
    #   @Description:  parse response code and body
    #
    #   @Date:
    #=====================================================================
    """
    if resp['status_code'] == 200:
        print('Success: successfully completed request\r')
    else:
        messageid = resp['message']['error']['@Message.ExtendedInfo'][0].get(
            'MessageId')
        if 'Format' in messageid:
            print('Failure: import failed due to invalid path')
        else:
            message = (
                resp['message']['error']['@Message.ExtendedInfo'][0].get(
                    'Message')).lower()
            print('Failure: ' + message[:-1])


def importsslcert(client, args):
    """
    #=====================================================================
    #   @Description:  import SSL certificate
    #
    #   @Date:
    #   @Modify: Modify the variable name of the receiving progress
    #   @Modify: The local import function is added.
    #=====================================================================
    """
    file_path = get_file_path(args, client)
    payload = {"Type": "URI", "Certificate": file_path}
    if args.Type == 'custom':
        if args.CertPassword is not None:
            payload["Password"] = args.CertPassword
        elif args.CertPasswordEnable == 'True':
            payload["Password"] = common_function.subcommand_pwd("SSL Cert", True)

    slotid = client.get_slotid()
    if slotid is None:
        return None

    url = get_url(args, slotid)
    resp_ssl = client.create_resource(url, payload)

    if resp_ssl is None:
        return None

    if resp_ssl.get('status_code') == 202:

        task_state = client.print_task_prog(resp_ssl)
        if task_state is None:
            return None

        if task_state == 'Exception':
            _resptaskparse(resp_ssl, client)
            sys.exit(144)

    else:
        _respparse(resp_ssl)

    return resp_ssl


def get_file_path(args, client):
    """
    Function Description: get file path
    Parameter:client redfishClient
    args object:CLI command
    Return Value: file_path
    """
    if args.Content is not None:
        file_path = args.Content
    elif args.file is not None:
        file_path = common_function.import_file_path(client, args.file)
    else:
        file_path = common_function.splice_remote_server_path(args)

    if file_path is None:
        sys.exit(2)
    return file_path


def get_url(args, slotid):
    """
    Function Description:get url
    Parameter:args object:CLI command
    slotid (str): server slot id
    Return Value: ssl cert url
    """
    url = None
    if args.Type == 'server':
        url = "/redfish/v1/Managers/%s/SecurityService/" % slotid + \
              "HttpsCert/Actions/HttpsCert.ImportServerCertificate"
    elif args.Type == 'custom':
        url = "/redfish/v1/Managers/%s/SecurityService/" % slotid + \
              "HttpsCert/Actions/HttpsCert.ImportCustomCertificate"
    return url


def check_parameter(_, args):
    """
    Function Description:check CLI command
    Parameter:args object:CLI command
    parser object:subcommand ArgumentParser object
    """
    if args.CertPassword is not None and args.CertPasswordEnable == 'True':
        print('-E is not needed in non-interactive command')
        sys.exit(common_function.UREST_STATUS_CODE_2)
    if (args.imageuri is not None or args.protocol is not None or
            args.accessuser is not None) and args.Content is not None:
        print("Failure: -C contains the information of -i -PRO and -U. you can not use -C and -i -PRO -U both.")
        sys.exit(common_function.UREST_STATUS_CODE_2)
    if args.Content is not None and not (common_function.verify_remote_server_info(args.Content)
             or args.Content.startswith("/tmp")):
        print('Failure: path of the SSL certificate.'
              ' On a local file server, the'
              ' certificate can be stored only'
              ' in the /tmp directory of iBMC,'
              ' and the path format is'
              ' /tmp/file name. On a remote file'
              ' server, the path format is protocol://'
              'User name:Password@IP address/'
              'Folder/File name. The file '
              'transfer protocols include the'
              ' following: sftp, https, nfs,' 
              ' cifs, scp.')
        sys.exit(common_function.UREST_STATUS_CODE_2)


def is_interactive(args):
    """
    Function Description:check CLI command
    Parameter:args object:CLI command
    parser object:subcommand ArgumentParser object
    """
    if args.Content is not None:
        return False
    return True
