###
# Copyright 2016-2021 Hewlett Packard Enterprise, Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#  http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
###

# -*- coding: utf-8 -*-
""" Status Command for RDMC """

from redfish.ris.utils import merge_dict

from ilorest.rdmc_helper import ReturnCodes, InvalidCommandLineErrorOPTS, Encryption, \
                                                    NoCurrentSessionEstablished

class StatusCommand():
    """ Constructor """
    def __init__(self):
        self.ident = {
            'name':'status',
            'usage': None,
            'description':'Run to display all pending changes within'
                    ' the currently\n\tselected type that need to be'
                    ' committed\n\texample: status',
            'summary':'Displays all pending changes within a selected type'
                      ' that need to be committed.',
            'aliases': [],
            'auxcommands': ['SelectCommand']
        }
        self.cmdbase = None
        self.rdmc = None
        self.auxcommands = dict()

    def run(self, line, help_disp=False):
        """ Main status worker function

        :param line: command line input
        :type line: string.
        """
        if help_disp:
            self.parser.print_help()
            return ReturnCodes.SUCCESS
        try:
            (options, _) = self.rdmc.rdmc_parse_arglist(self, line)
        except (InvalidCommandLineErrorOPTS, SystemExit):
            if ("-h" in line) or ("--help" in line):
                # self.rdmc.ui.printer(self.ident['usage'])
                return ReturnCodes.SUCCESS
            else:
                raise InvalidCommandLineErrorOPTS("")

        self.statusvalidation(options)
        contents = self.rdmc.app.status()
        selector = self.rdmc.app.selector

        if contents and options.json:
            self.jsonout(contents)
        elif contents:
            self.outputpatches(contents, selector)
        else:
            self.rdmc.ui.printer("No changes found\n")

        #Return code
        return ReturnCodes.SUCCESS

    def jsonout(self, contents):
        """ Helper function to print json output of patches

        :param contents: contents for the selection
        :type contents: string.
        """
        self.rdmc.ui.printer("Current changes found:\n")
        createdict = lambda y, x: {x:y}
        totdict = {}
        for item in contents:
            for keypath, value in item.items():
                path = keypath.split('(')[1].strip('()')
                cont = {}
                totdict[path] = cont
                for content in value:
                    val = ["List Manipulation"] if content['op'] == 'move' else \
                        [content["value"].strip('"\'')] if len(content["value"]) else [""]
                    cont = reduce(createdict, reversed([path]+content['path'].strip('/').\
                                  split('/')+val))
                    merge_dict(totdict, cont)
        self.rdmc.ui.print_out_json(totdict)

    def outputpatches(self, contents, selector):
        """ Helper function for status for use in patches

        :param contents: contents for the selection
        :type contents: string.
        :param selector: type selected
        :type selector: string.
        """
        self.rdmc.ui.printer("Current changes found:\n")
        for item in contents:
            moveoperation = ""
            for key, value in item.items():
                if selector and key.lower().startswith(selector.lower()):
                    self.rdmc.ui.printer("%s (Currently selected)\n" % key)
                else:
                    self.rdmc.ui.printer("%s\n" % key)

                for content in value:
                    try:
                        if content['op'] == 'move':
                            moveoperation = '/'.join(content['path'].split('/')[1:-1])
                            continue
                    except:
                        if content[0]['op'] == 'move':
                            moveoperation = '/'.join(content[0]['path'].split('/')[1:-1])
                            continue
                    try:
                        if isinstance(content[0]["value"], int):
                            self.rdmc.ui.printer('\t%s=%s' % \
                                 (content[0]["path"][1:], content[0]["value"]))
                        elif not isinstance(content[0]["value"], bool) and \
                                            not len(content[0]["value"]) == 0:
                            if content[0]["value"][0] == '"' and \
                                                content[0]["value"][-1] == '"':
                                self.rdmc.ui.printer('\t%s=%s' % (content[0]["path"][1:],
                                                                  content[0]["value"][1:-1]))
                            else:
                                self.rdmc.ui.printer('\t%s=%s' % (content[0]["path"][1:],
                                                                  content[0]["value"]))
                        else:
                            output = content[0]["value"]

                            if not isinstance(output, bool):
                                if len(output) == 0:
                                    output = '""'

                            self.rdmc.ui.printer('\t%s=%s' % (content[0]["path"][1:], output))
                    except:
                        if isinstance(content["value"], int):
                            self.rdmc.ui.printer('\t%s=%s' % (content["path"][1:],
                                                              content["value"]))
                        elif not isinstance(content["value"], bool) and \
                                                not len(content["value"]) == 0:
                            if content["value"][0] == '"' and \
                                                    content["value"][-1] == '"':
                                self.rdmc.ui.printer('\t%s=%s' % (content["path"][1:],
                                                                  content["value"]))
                            else:
                                self.rdmc.ui.printer('\t%s=%s' % (content["path"][1:],
                                                                  content["value"]))
                        else:
                            output = content["value"]

                            if not isinstance(output, bool):
                                if len(output) == 0:
                                    output = '""'

                            self.rdmc.ui.printer('\t%s=%s' % (content["path"][1:], output))
                    self.rdmc.ui.printer('\n')
            if moveoperation:
                self.rdmc.ui.printer("\t%s=List Manipulation\n" % moveoperation)

    def statusvalidation(self, options):
        """ Status method validation function """

        self.cmdbase.login_select_validation(self, options)

    def definearguments(self, customparser):
        """ Wrapper function for new command main function

        :param customparser: command line input
        :type customparser: parser.
        """
        if not customparser:
            return

        self.cmdbase.add_login_arguments_group(customparser)

        customparser.add_argument(
            '-j',
            '--json',
            dest='json',
            action="store_true",
            help="Optionally include this flag if you wish to change the"\
            " displayed output to JSON format. Preserving the JSON data"\
            " structure makes the information easier to parse.",
            default=False
        )
