# -*- utf-8 -*-
"""
Function: import_remote_https_server_cert.py moudle. This moudle mainly
 involves the importing the certificate of the remote HTTPS transport
  server function.
Copyright Information: xFusion Digital Technologies Co.,
 Ltd. All Rights Reserved © 2021
"""
import os
import sys

from scripts import common_function

url_dict = {
    "root": "/redfish/v1/Managers/{}/SecurityService/Actions/"
            "SecurityService.ImportRemoteHttpsServerRootCA",
    "crl": "/redfish/v1/Managers/{}/SecurityService/Actions/"
           "SecurityService.ImportRemoteHttpsServerCrl"}

import_error = "failed to import the certificate."
type_crl = "crl"


def import_remote_https_server_cert_init(parser, parser_dict):
    """
    Function Description:initializing the Command for
    importing the certificate of the remote HTTPS transport server.
    Parameter:parser object: action object
              parser_dict dict: dictionary format of subcommand and
               ArgumentParser
    """
    sub_parser = parser.add_parser(common_function.HTTPS_SUB_COMMAND,
                                   help="importing the crl or the root"
                                        " certificate of a remote https"
                                        " server.")
    sub_parser.add_argument('-c', dest='content',
                            required=False, default=None,
                            help='path of the crl or the root certificate.'
                                 ' the certificate can be stored only 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("-T",
                            choices=["root", type_crl],
                            dest="type", required=True,
                            help="root certificate or CRL of the"
                                 " remote HTTPS server.")
    sub_parser.add_argument("-RCI",
                            dest="root_cert_id",
                            help="id of the root certificate used by the remote"
                                 " HTTPS server to authenticate or issue"
                                 " the CRL",
                            choices=["1", "2", "3", "4", "5", "6", "7", "8"],
                            required=False)
    sub_parser.add_argument("-USAGE",
                            dest="usage",
                            choices=["EventSubscription", "FileTransfer"],
                            help="usage of the certificate")
    sub_parser.add_argument("-F",
                            dest="file", required=False,
                            default=None,
                            help="the local path for the certificate or CRL of"
                                 " the remote HTTPS server"
                                 " is /folder/file name.")
    image_uri = {
        common_function.REQUIRED_FLAG: False,
        common_function.HELP_INFO: 'path of the crl or the root certificate.'
                                   ' the certificate can be stored only 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[common_function.HTTPS_SUB_COMMAND] = sub_parser
    return common_function.HTTPS_SUB_COMMAND


def check_parameter(parser, args):
    """
    Function Description:check CLI command
    Parameter:args object:CLI command
    """
    if (args.imageuri is not None or args.protocol is not None or
            args.accessuser is not None) and args.content is not None:
        parser.error("-c contains the information of -i -PRO and -U. you can not use -c and -i -PRO -U both.")
    if args.content is not None and not (common_function.verify_remote_server_info(args.content)
             or args.content.startswith("/tmp")):
        parser.error('path of the crl or the root certificate.'
                     ' the certificate can be stored only 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.')
    extension_names = [".crl"] if args.type == type_crl else [".pem", ".crt", ".cer"]
    if args.content is not None:
        file_path = args.content
    elif args.file is not None:
        file_path = args.file
    else:
        file_path = args.imageuri
    if os.path.splitext(file_path)[-1] not in extension_names:
        parser.error('the certificate file extension'
                     ' must be %s.' % ",".join(extension_names))

    if all(cert_identifier is None for cert_identifier in (args.root_cert_id,
                                                           args.usage)):
        parser.error('specify at least one of the -RCI and -USAGE parameters.')


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


def get_payload(client, args):
    """
    Function Description:get payload
    Parameter:args object:CLI command
    """
    cert_id = int(args.root_cert_id) if args.root_cert_id is not None else None
    if args.file is not None:
        path = common_function.import_file_path(client, args.file)
    else:
        if args.content is not None:
            path = args.content
        else:
            path = common_function.splice_remote_server_path(args)

    if path is None:
        sys.exit(common_function.UREST_STATUS_CODE_2)

    keys = ("Type", "Content", "RootCertId", "Usage")
    values = ("URI", path, cert_id, args.usage)
    payload_dict = dict(zip(keys, values))

    return {key: value for key, value in payload_dict.items() if
            value is not None}


def import_remote_https_server_cert(client, args):
    """
    Function Description:Importing a Dual-Factor Certificate
    Parameter:client refishClient: class object
              args object:CLI command
    """
    slot_id = client.get_slotid()
    if slot_id is None:
        sys.exit(common_function.UREST_STATUS_CODE_127)

    url = url_dict.get(args.type).format(slot_id)
    payload = get_payload(client, args)
    resp = client.create_resource(url, payload)
    if not resp:
        raise common_function.CustomError(import_error)

    if resp.get('status_code') == common_function.REDFISH_STATUS_CODE_200:
        print('Success: successfully completed request')

    elif resp.get('status_code') == common_function.REDFISH_STATUS_CODE_202:
        resp_task = client.print_task_prog(resp)
        if not resp_task:
            raise common_function.CustomError(import_error)

        if resp_task == "Exception":
            resp_progress = client.get_resource(resp['resource']['@odata.id'])
            if resp_progress.get(
                    'status_code') != common_function.REDFISH_STATUS_CODE_200:
                raise common_function.CustomError(resp_progress)

            raise common_function.CustomError(
                resp_progress['resource']['Messages']['Message'],
                code=common_function.REDFISH_STATUS_CODE_400)
    else:
        raise common_function.CustomError(resp)

    return resp
