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

slotid = None
file_path = None


def getdiaginfo_init(parser, parser_dict):
    """
    Function Description: initializing the Command for
    collecting Information in One Click.
    Parameter: parser object: action object
               parser_dict dict: dictionary format of subcommand and
               ArgumentParser
    Modify: 2019.4.28 The help information is optimized.
            2021.3.8 The help information of -F is optimized.
    Return Value: subcommand
    """
    sub_parser = parser.add_parser('getdiaginfo',
                                   help='''get diagnosis information''')

    sub_parser.add_argument('-c', dest='content',
                            type=str, required=False,
                            help='path of the file that is'
                                 ' collected in one-click mode.'
                                 ' On a local file server, the file'
                                 ' can be stored only in the'
                                 ' /tmp directory of iBMC. 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 local path of file: Folder/File name.')

    image_uri = {common_function.REQUIRED_FLAG: False,
                 common_function.HELP_INFO: 'path of the file that is'
                                            ' collected in one-click mode.'
                                            ' On a local file server, the file'
                                            ' can be stored only in the'
                                            ' /tmp directory of iBMC. 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['getdiaginfo'] = sub_parser

    return 'getdiaginfo'


def getdiaginfo(client, args):
    """
    #==========================================================================
    # @Method: One-click collection
    # @command: getdiaginfo
    # @Param:client, parser, args
    # @Return: None
    # @date: 2017.7.21
    # @Modify: Modify the variable name of the receiving progress
    # @Modify: The local export function is added.
    #==========================================================================
    """
    global file_path
    file_path = get_file_path(args)
    payload = {"Type": "URI", "Content": file_path}

    # Obtain the slot number.
    global slotid
    slotid = client.get_slotid()
    if slotid is None:
        return None

    # Construct the URI of POST operations.
    url = "/redfish/v1/Managers/%s/Actions/Oem/%s/M" \
          "anager.Dump" % (slotid, common_function.COMMON_KEY)
    # Perform POST operations. resp indicates the entire response information,
    # including the response body and the status code.
    # 2021.3.3 Modify: Changing the default timeout interval.
    resp = client.create_resource(url, payload,
                                  timeout=common_function.TIMEOUT_UPDATE)
    if resp is None:
        return None

    # The latency is 2 seconds. Wait until the task percentage value changes
    # to a value greater than or equal to 0%, and display information.
    time.sleep(2)
    if resp['status_code'] == 202:
        resp = print_succ_info(args, client, resp)
    elif resp['status_code'] == 404:
        print("Failure: resource was not found")
    elif resp['status_code'] == 400:
        error_message = resp['message']['error']['@Message.ExtendedInfo'][0]
        error_parse(error_message)
    else:
        message = (resp['message']['error']['@Message.ExtendedInfo'][0][
                       'Message']).lower()
        print('Failure: ' + message)
    return resp


def print_succ_info(args, client, resp):
    """
     功能描述:打印成功的信息到控制台
     参数：args (list): parameter list
     client (RedfishClient):
     resp (dict):通过打印日志接口获取的资源结果
     返回值：resp (dict)：redfish接口请求回来的结果
     修改：None
     """
    resp_task = client.print_task_prog(resp,
                                       maxtime=common_function.MAX_TIMEOUT,
                                       flag="getdiaginfo")
    if resp_task is None:
        return None
    # Handle exceptions.
    if resp_task == 'Exception':
        taskstate(client, resp)
        sys.exit(144)
    if resp_task == 'Completed':
        if args.file is not None:
            common_function.export_local_path(client, slotid, file_path,
                                              args)
        print('Success: successfully completed request\n')
    return resp


def get_file_path(args):
    """
    Function Description: get file path
    Parameter:args object:CLI command
    Return Value: path str:csr file path
    """
    if args.content is not None:
        path = args.content
    elif args.file is not None:
        path = common_function.set_file_path(args.file)
    else:
        path = common_function.splice_remote_server_path(args)

    if path is None:
        sys.exit(2)

    return path


def check_parameter(parser, args):
    """
    Function Description:check CLI command
    Parameter:args object:CLI command
    parser object:subcommand ArgumentParser object
    Add: 2021.3.15 The file name extension check is added.
    """
    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.")
        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")):
        parser.error('path of the file that is'
                     ' collected in one-click mode.'
                     ' On a local file server, the file'
                     ' can be stored only in the'
                     ' /tmp directory of iBMC. 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.')
    if args.file and not args.file.endswith("tar.gz"):
        parser.error("Failure: The file format of the -F parameter"
                     " is incorrect, which must be tar.gz.")
    if args.imageuri and not args.imageuri.endswith("tar.gz"):
        parser.error("Failure: The file format of the -i parameter"
                     " is incorrect, which must be tar.gz.")


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 error_parse(error_message):
    """
    #==========================================================================
    # @Method: Display error information.
    # @Param: error_message
    # @date: 2017.7.21
    #==========================================================================
    """
    # Parameter verification
    if error_message is None:
        return None

    # Obtain the value of MessageId.
    messageid = error_message['MessageId'].split('.')[-1]

    # Obtain the value of formatted 'message'.
    message = error_message['Message'].lower()
    if message[-1] == '.':
        message = (message[:-1])

    # Display messages according to the specific MessageId values
    # (repeated operation, upgrade environment,
    # insufficient tmp directory memory)
    if messageid in ['DumpExportingErr', 'UpgradingErr',
                     'InsufficientMemoryErr']:
        print("Failure: %s" % message)
    elif messageid in ['InvalidPath', 'PropertyValueFormatError']:
        print("Failure: export failed due to invalid path")
    return None


def taskstate(client, resp):
    """
    #==========================================================================
    # @Method: Handle exceptions
    # @Param: client, resp
    # @date: 2017.7.21
    #==========================================================================
    """
    # Obtain the task ID.
    taskid = resp['resource']['@odata.id']
    # Perform the GET operation again to obtain the message body.
    task_resp = client.get_resource(taskid)
    if task_resp is None:
        return None
    if task_resp['status_code'] != 200:
        message = (task_resp['message']['error']['@Message.ExtendedInfo'][0][
                       'Message']).lower()
        print('Failure: ' + message[:-1])
    else:
        message = (task_resp['resource']['Messages']['Message']).lower()
        print('Failure: ' + message[:-1])
    return task_resp
