#!/usr/bin/env python
#
# Copyright 2016 the original author or authors.
#
# 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.
#

"""
Device level CLI commands
"""
from optparse import make_option
from cmd2 import Cmd, options
from simplejson import dumps

from table import print_pb_as_table, print_pb_list_as_table
from utils import print_flows, pb2dict, enum2name

from voltha_protos import voltha_pb2, common_pb2
import sys
import json
from google.protobuf.json_format import MessageToDict

# Since proto3 won't send fields that are set to 0/false/"" any object that
# might have those values set in them needs to be replicated here such that the
# fields can be adequately


class DeviceCli(Cmd):

    def __init__(self, device_id, get_stub):
        Cmd.__init__(self)
        self.get_stub = get_stub
        self.device_id = device_id
        self.prompt = '(' + self.colorize(
            self.colorize('device {}'.format(device_id), 'red'), 'bold') + ') '
        self.pm_config_last = None
        self.pm_config_dirty = False

    def cmdloop(self):
        self._cmdloop()

    def get_device(self, depth=0):
        stub = self.get_stub()
        res = stub.GetDevice(voltha_pb2.ID(id=self.device_id),
                             metadata=(('get-depth', str(depth)), ))
        return res

    do_exit = Cmd.do_quit

    def do_quit(self, line):
        if self.pm_config_dirty:
            self.poutput("Uncommited changes for " + \
                         self.colorize(
                             self.colorize("perf_config,", "blue"),
                             "bold") + " please either " + self.colorize(
                             self.colorize("commit", "blue"), "bold") + \
                         " or " + self.colorize(
                             self.colorize("reset", "blue"), "bold") + \
                         " your changes using " + \
                         self.colorize(
                             self.colorize("perf_config", "blue"), "bold"))
            return False
        else:
            return self._STOP_AND_EXIT

    def do_show(self, line):
        """Show detailed device information"""
        print_pb_as_table('Device {}'.format(self.device_id),
                          self.get_device(depth=-1))

    def do_ports(self, line):
        """Show ports of device"""
        device = self.get_device(depth=-1)
        omit_fields = {
        }
        print_pb_list_as_table('Device ports:', device.ports,
                               omit_fields, self.poutput)

    def complete_perf_config(self, text, line, begidx, endidx):
        sub_cmds = {"show", "set", "commit", "reset"}
        sub_opts = {"-f", "-e", "-d", "-o"}
        # Help the interpreter complete the paramters.
        completions = []
        if not self.pm_config_last:
            device = self.get_device(depth=-1)
            self.pm_config_last = device.pm_configs
        m_names = [d.name for d in self.pm_config_last.metrics]
        cur_cmd = line.strip().split(" ")
        try:
            if not text and len(cur_cmd) == 1:
                completions = ("show", "set", "commit", "reset")
            elif len(cur_cmd) == 2:
                if "set" == cur_cmd[1]:
                    completions = [d for d in sub_opts]
                else:
                    completions = [d for d in sub_cmds if d.startswith(text)]
            elif len(cur_cmd) > 2 and cur_cmd[1] == "set":
                if cur_cmd[len(cur_cmd)-1] == "-":
                    completions = [list(d)[1] for d in sub_opts]
                elif cur_cmd[len(cur_cmd)-1] == "-f":
                    completions = ("\255","Please enter a sampling frequency in 10ths of a second")
                elif cur_cmd[len(cur_cmd)-2] == "-f":
                    completions = [d for d in sub_opts]
                elif cur_cmd[len(cur_cmd)-1] in {"-e","-d","-o"}:
                    if self.pm_config_last.grouped:
                        pass
                    else:
                        completions = [d.name for d in self.pm_config_last.metrics]
                elif cur_cmd[len(cur_cmd)-2] in {"-e","-d"}:
                    if text and text not in m_names:
                        completions = [d for d in m_names if d.startswith(text)]
                    else:
                        completions = [d for d in sub_opts]
                elif cur_cmd[len(cur_cmd)-2] == "-o":
                    if cur_cmd[len(cur_cmd)-1] in [d.name for d in self.pm_config_last.metrics]:
                        completions = ("\255","Please enter a sampling frequency in 10ths of a second")
                    else:
                        completions = [d for d in m_names if d.startswith(text)]
                elif cur_cmd[len(cur_cmd)-3] == "-o":
                    completions = [d for d in sub_opts]
        except:
            e = sys.exc_info()
            print(e)
        return completions


    def help_perf_config(self):
        self.poutput(
'''
perf_config [show | set | commit | reset] [-f <default frequency>] [{-e <metric/group
            name>}] [{-d <metric/group name>}] [{-o <metric/group name> <override
            frequency>}]

show: displays the performance configuration of the device
set: changes the parameters specified with -e, -d, and -o
reset: reverts any changes made since the last commit
commit: commits any changes made which applies them to the device.

-e: enable collection of the specified metric, more than one -e may be
            specified.
-d: disable collection of the specified metric, more than on -d may be
            specified.
-o: override the collection frequency of the specified metric, more than one -o
            may be specified. Note that -o isn't valid unless
            frequency_override is set to True for the device.

Changes made by set are held locally until a commit or reset command is issued.
A commit command will write the configuration to the device and it takes effect
immediately. The reset command will undo any changes since the start of the
device session.

If grouped is true then the -d, -e and -o commands refer to groups and not
individual metrics.
'''
        )

    @options([
        make_option('-f', '--default_freq', action="store", dest='default_freq',
                    type='long', default=None),
        make_option('-e', '--enable', action='append', dest='enable',
                    default=None),
        make_option('-d', '--disable', action='append', dest='disable',
                    default=None),
        make_option('-o', '--override', action='append', dest='override',
                    nargs=2, default=None, type='string'),
    ])
    def do_perf_config(self, line, opts):
        """Show and set the performance monitoring configuration of the device"""

        device = self.get_device(depth=-1)
        if not self.pm_config_last:
            self.pm_config_last = device.pm_configs

        # Ensure that a valid sub-command was provided
        if line.strip() not in {"set", "show", "commit", "reset", ""}:
                self.poutput(self.colorize('Error: ', 'red') +
                             self.colorize(self.colorize(line.strip(), 'blue'),
                                           'bold') + ' is not recognized')
                return

        # Ensure no options are provided when requesting to view the config
        if line.strip() == "show" or line.strip() == "":
            if opts.default_freq or opts.enable or opts.disable:
                self.poutput(opts.disable)
                self.poutput(self.colorize('Error: ', 'red') + 'use ' +
                             self.colorize(self.colorize('"set"', 'blue'),
                                           'bold') + ' to change settings')
                return

        if line.strip() == "set":  # Set the supplied values
            metric_list = set()
            if opts.enable is not None:
                metric_list |= {metric for metric in opts.enable}
            if opts.disable is not None:
                metric_list |= {metric for metric in opts.disable}
            if opts.override is not None:
                metric_list |= {metric for metric, _ in opts.override}

            # The default frequency
            if opts.default_freq:
                self.pm_config_last.default_freq = opts.default_freq
                self.pm_config_dirty = True

            # Field or group visibility
            if self.pm_config_last.grouped:
                for g in self.pm_config_last.groups:
                    if opts.enable:
                        if g.group_name in opts.enable:
                            g.enabled = True
                            self.pm_config_dirty = True
                            metric_list.discard(g.group_name)
                for g in self.pm_config_last.groups:
                    if opts.disable:
                        if g.group_name in opts.disable:
                            g.enabled = False
                            self.pm_config_dirty = True
                            metric_list.discard(g.group_name)
            else:
                for m in self.pm_config_last.metrics:
                    if opts.enable:
                        if m.name in opts.enable:
                            m.enabled = True
                            self.pm_config_dirty = True
                            metric_list.discard(m.name)
                for m in self.pm_config_last.metrics:
                    if opts.disable:
                        if m.name in opts.disable:
                            m.enabled = False
                            self.pm_config_dirty = True
                            metric_list.discard(m.name)

            # Frequency overrides.
            if opts.override:
                if self.pm_config_last.freq_override:
                    oo = dict()
                    for o in opts.override:
                        oo[o[0]] = o[1]
                    if self.pm_config_last.grouped:
                        for g in self.pm_config_last.groups:
                            if g.group_name in oo:
                                try:
                                    g.group_freq = int(oo[g.group_name])
                                except ValueError:
                                    self.poutput(self.colorize('Warning: ',
                                                               'yellow') +
                                                 self.colorize(oo[g.group_name],
                                                               'blue') +
                                                 " is not an integer... ignored")
                                del oo[g.group_name]
                                self.pm_config_dirty = True
                                metric_list.discard(g.group_name)
                    else:
                        for m in self.pm_config_last.metrics:
                            if m.name in oo:
                                try:
                                    m.sample_freq = int(oo[m.name])
                                except ValueError:
                                    self.poutput(self.colorize('Warning: ',
                                                               'yellow') +
                                                 self.colorize(oo[m.name],
                                                               'blue') +
                                                 " is not an integer... ignored")
                                del oo[m.name]
                                self.pm_config_dirty = True
                                metric_list.discard(m.name)

                    # If there's anything left the input was typoed
                    if self.pm_config_last.grouped:
                        field = 'group'
                    else:
                        field = 'metric'
                    for o in oo:
                        self.poutput(self.colorize('Warning: ', 'yellow') +
                                     'the parameter' + ' ' +
                                     self.colorize(o, 'blue') + ' is not ' +
                                     'a ' + field + ' name... ignored')
                    if oo:
                        return

                else:  # Frequency overrides not enabled
                    self.poutput(self.colorize('Error: ', 'red') +
                                 'Individual overrides are only ' +
                                 'supported if ' +
                                 self.colorize('freq_override', 'blue') +
                                 ' is set to ' + self.colorize('True', 'blue'))
                    return

            if len(metric_list):
                metric_name_list = ", ".join(str(metric) for metric in metric_list)
                self.poutput(self.colorize('Error: ', 'red') +
                             'Metric/Metric Group{} '.format('s' if len(metric_list) > 1 else '') +
                             self.colorize(metric_name_list, 'blue') +
                             ' {} not found'.format('were' if len(metric_list) > 1 else 'was'))
                return

            self.poutput("Success")
            return

        elif line.strip() == "commit" and self.pm_config_dirty:
            stub = self.get_stub()
            stub.UpdateDevicePmConfigs(self.pm_config_last)
            self.pm_config_last = self.get_device(depth=-1).pm_configs
            self.pm_config_dirty = False

        elif line.strip() == "reset" and self.pm_config_dirty:
            self.pm_config_last = self.get_device(depth=-1).pm_configs
            self.pm_config_dirty = False

        omit_fields = {'groups', 'metrics', 'id'}
        print_pb_as_table('PM Config:', self.pm_config_last, omit_fields,
                          self.poutput,show_nulls=True)
        if self.pm_config_last.grouped:
            #self.poutput("Supported metric groups:")
            for g in self.pm_config_last.groups:
                if self.pm_config_last.freq_override:
                    omit_fields = {'metrics'}
                else:
                    omit_fields = {'group_freq','metrics'}
                print_pb_as_table('', g, omit_fields, self.poutput,
                                  show_nulls=True)
                if g.enabled:
                    state = 'enabled'
                else:
                    state = 'disabled'
                print_pb_list_as_table(
                    'Metric group {} is {}'.format(g.group_name,state),
                    g.metrics, {'enabled', 'sample_freq'}, self.poutput,
                    dividers=100, show_nulls=True)
        else:
            if self.pm_config_last.freq_override:
                omit_fields = {}
            else:
                omit_fields = {'sample_freq'}
            print_pb_list_as_table('Supported metrics:', self.pm_config_last.metrics,
                                   omit_fields, self.poutput, dividers=100,
                                   show_nulls=True)

    def do_flows(self, line):
        """Show flow table for device"""
        device = pb2dict(self.get_device(-1))
        print_flows(
            'Device',
            self.device_id,
            type=device['type'],
            flows=device['flows']['items'],
            groups=device['flow_groups']['items']
        )

    def do_images(self, line):
        """Show software images on the device"""
        device = self.get_device(depth=-1)
        omit_fields = {}
        print_pb_list_as_table('Software Images:', device.images.image,
                               omit_fields, self.poutput, show_nulls=True)

    @options([
        make_option('-u', '--url', action='store', dest='url',
                    help="URL to get sw image"),
        make_option('-n', '--name', action='store', dest='name',
                    help="Image name"),
        make_option('-c', '--crc', action='store', dest='crc',
                    help="CRC code to verify with", default=0),
        make_option('-v', '--version', action='store', dest='version',
                    help="Image version", default=0),
    ])
    def do_img_dnld_request(self, line, opts):
        """
        Request image download to a device
        """
        device = self.get_device(depth=-1)
        self.poutput('device_id {}'.format(device.id))
        self.poutput('name {}'.format(opts.name))
        self.poutput('url {}'.format(opts.url))
        self.poutput('crc {}'.format(opts.crc))
        self.poutput('version {}'.format(opts.version))
        try:
            device_id = device.id
            if device_id and opts.name and opts.url:
                kw = dict(id=device_id)
                kw['name'] = opts.name
                kw['url'] = opts.url
            else:
                self.poutput('Device ID and URL are needed')
                raise Exception('Device ID and URL are needed')
        except Exception as e:
            self.poutput('Error request img dnld {}.  Error:{}'.format(device_id, e))
            return
        kw['crc'] = long(opts.crc)
        kw['image_version'] = opts.version
        response = None
        try:
            request = voltha_pb2.ImageDownload(**kw)
            stub = self.get_stub()
            response = stub.DownloadImage(request)
        except Exception as e:
            self.poutput('Error download image {}. Error:{}'.format(kw['id'], e))
            return
        name = enum2name(common_pb2.OperationResp,
                        'OperationReturnCode', response.code)
        self.poutput('response: {}'.format(name))
        self.poutput('{}'.format(response))

    @options([
        make_option('-n', '--name', action='store', dest='name',
                    help="Image name"),
    ])
    def do_img_dnld_status(self, line, opts):
        """
        Get a image download status
        """
        device = self.get_device(depth=-1)
        self.poutput('device_id {}'.format(device.id))
        self.poutput('name {}'.format(opts.name))
        try:
            device_id = device.id
            if device_id and opts.name:
                kw = dict(id=device_id)
                kw['name'] = opts.name
            else:
                self.poutput('Device ID, Image Name are needed')
                raise Exception('Device ID, Image Name are needed')
        except Exception as e:
            self.poutput('Error get img dnld status {}.  Error:{}'.format(device_id, e))
            return
        status = None
        try:
            img_dnld = voltha_pb2.ImageDownload(**kw)
            stub = self.get_stub()
            status = stub.GetImageDownloadStatus(img_dnld)
        except Exception as e:
            self.poutput('Error get img dnld status {}. Error:{}'.format(device_id, e))
            return
        fields_to_omit = {
              'crc',
              'local_dir',
        }
        try:
            print_pb_as_table('ImageDownload Status:', status, fields_to_omit, self.poutput)
        except Exception, e:
            self.poutput('Error {}.  Error:{}'.format(device_id, e))

    def do_img_dnld_list(self, line):
        """
        List all image download records for a given device
        """
        device = self.get_device(depth=-1)
        device_id = device.id
        self.poutput('Get all img dnld records {}'.format(device_id))
        try:
            stub = self.get_stub()
            img_dnlds = stub.ListImageDownloads(voltha_pb2.ID(id=device_id))
        except Exception, e:
            self.poutput('Error list img dnlds {}.  Error:{}'.format(device_id, e))
            return
        fields_to_omit = {
              'crc',
              'local_dir',
        }
        try:
            print_pb_list_as_table('ImageDownloads:', img_dnlds.items, fields_to_omit, self.poutput)
        except Exception, e:
            self.poutput('Error {}.  Error:{}'.format(device_id, e))


    @options([
        make_option('-n', '--name', action='store', dest='name',
                    help="Image name"),
    ])
    def do_img_dnld_cancel(self, line, opts):
        """
        Cancel a requested image download
        """
        device = self.get_device(depth=-1)
        self.poutput('device_id {}'.format(device.id))
        self.poutput('name {}'.format(opts.name))
        device_id = device.id
        try:
            if device_id and opts.name:
                kw = dict(id=device_id)
                kw['name'] = opts.name
            else:
                self.poutput('Device ID, Image Name are needed')
                raise Exception('Device ID, Image Name are needed')
        except Exception as e:
            self.poutput('Error cancel sw dnld {}. Error:{}'.format(device_id, e))
            return
        response = None
        try:
            img_dnld = voltha_pb2.ImageDownload(**kw)
            stub = self.get_stub()
            img_dnld = stub.GetImageDownload(img_dnld)
            response = stub.CancelImageDownload(img_dnld)
        except Exception as e:
            self.poutput('Error cancel sw dnld {}. Error:{}'.format(device_id, e))
            return
        name = enum2name(common_pb2.OperationResp,
                        'OperationReturnCode', response.code)
        self.poutput('response: {}'.format(name))
        self.poutput('{}'.format(response))

    def help_simulate_alarm(self):
        self.poutput(
'''
simulate_alarm <alarm_name> [-b <bit rate>] [-c] [-d <drift>] [-e <eqd>]
            [-i <interface id>] [-o <onu device id>] [-p <port type name>]

<name> is the name of the alarm to raise. Other rguments are alarm specific
and only have meaning in the context of a particular alarm. Below is a list
of the alarms that may be raised:

simulate_alarm los -i <interface_id> -p <port_type_name>
simulate_alarm dying_gasp -i <interface_id> -o <onu_device_id>
simulate_alarm onu_los -i <interface_id> -o <onu_device_id>
simulate_alarm onu_lopc_miss -i <interface_id> -o <onu_device_id>
simulate_alarm onu_lopc_mic -i <interface_id> -o <onu_device_id>
simulate_alarm onu_lob -i <interface_id> -o <onu_device_id>
simulate_alarm onu_signal_degrade -i <interface_id> -o <onu_device_id>
               -b <bit_rate>
simulate_alarm onu_drift_of_window -i <interface_id>
               -o <onu_device_id> -d <drift> -e <eqd>
simulate_alarm onu_signal_fail -i <interface_id> -o <onu_device_id>
               -b <bit_rate>
simulate_alarm onu_activation -i <interface_id> -o <onu_device_id>
simulate_alarm onu_startup -i <interface_id> -o <onu_device_id>
simulate_alarm onu_discovery -i <interface_id> -s <onu_serial_number>

If the -c option is specified then the alarm will be cleared. By default,
it will be raised. Note that only some alarms can be cleared.
'''
        )

    @options([
        make_option('-c', '--clear', action='store_true', default=False,
                    help="Clear alarm instead of raising"),
        make_option('-b', '--inverse_bit_error_rate', action='store', dest='inverse_bit_error_rate',
                    help="Inverse bit error rate", default=0, type="int"),
        make_option('-d', '--drift', action='store', dest='drift',
                    help="Drift", default=0, type="int"),
        make_option('-e', '--new_eqd', action='store', dest='new_eqd',
                    help="New EQD", default=0, type="int"),
        make_option('-i', '--intf_id', action='store', dest='intf_id',
                    help="Interface ID", default=""),
        make_option('-o', '--onu_device_id', action='store', dest='onu_device_id',
                    help="ONU device ID", default=""),
        make_option('-p', '--port_type_name', action='store', dest='port_type_name',
                    help="Port type name", default=""),
        make_option('-s', '--onu_serial_number', action='store', dest='onu_serial_number',
                    help="ONU Serial Number", default=""),
    ])
    def do_simulate_alarm(self, line, opts):
        indicator = line
        device = self.get_device(depth=-1)
        device_id = device.id

        alarm_args = {"los": ["intf_id", "port_type_name"],
                      "dying_gasp": ["intf_id", "onu_device_id"],
                      "onu_los": ["intf_id", "onu_device_id"],
                      "onu_lopc_miss": ["intf_id", "onu_device_id"],
                      "onu_lopc_mic": ["intf_id", "onu_device_id"],
                      "onu_lob": ["intf_id", "onu_device_id"],
                      "onu_signal_degrade": ["intf_id", "onu_device_id", "inverse_bit_error_rate"],
                      "onu_drift_of_window": ["intf_id", "onu_device_id", "drift", "new_eqd"],
                      "onu_signal_fail": ["intf_id", "onu_device_id", "inverse_bit_error_rate"],
                      "onu_activation": ["intf_id", "onu_device_id"],
                      "onu_startup": ["intf_id", "onu_device_id"],
                      "onu_discovery": ["intf_id", "onu_serial_number"]
                      }
        try:
            if indicator not in alarm_args:
                self.poutput("Unknown alarm indicator %s. Valid choices are %s." % (indicator,
                                                                                    ", ".join(alarm_args.keys())))
                raise Exception("Unknown alarm indicator %s" % indicator)

            for arg_name in alarm_args[indicator]:
                if not getattr(opts, arg_name):
                    self.poutput("Option %s is required for alarm %s. See help." % (arg_name, indicator))
                    raise Exception("Option %s is required for alarm %s" % (arg_name, indicator))

            # TODO: check for required arguments
            kw = dict(id=device_id)

            kw["indicator"] = indicator
            kw["intf_id"] = opts.intf_id
            kw["onu_device_id"] = opts.onu_device_id
            kw["port_type_name"] = opts.port_type_name
            kw["inverse_bit_error_rate"] = opts.inverse_bit_error_rate
            kw["drift"] = opts.drift
            kw["new_eqd"] = opts.new_eqd
            kw["onu_serial_number"] = opts.onu_serial_number

            if opts.clear:
                kw["operation"] = voltha_pb2.SimulateAlarmRequest.CLEAR
            else:
                kw["operation"] = voltha_pb2.SimulateAlarmRequest.RAISE
        except Exception as e:
            self.poutput('Error simulate alarm {}. Error:{}'.format(device_id, e))
            return
        response = None
        try:
            simulate_alarm = voltha_pb2.SimulateAlarmRequest(**kw)
            stub = self.get_stub()
            response = stub.SimulateAlarm(simulate_alarm)
        except Exception as e:
            self.poutput('Error simulate alarm {}. Error:{}'.format(kw['id'], e))
            return
        name = enum2name(common_pb2.OperationResp,
                        'OperationReturnCode', response.code)
        self.poutput('response: {}'.format(name))
        self.poutput('{}'.format(response))

    @options([
        make_option('-n', '--name', action='store', dest='name',
                    help="Image name"),
        make_option('-s', '--save', action='store', dest='save_config',
                    help="Save Config", default="True"),
        make_option('-d', '--dir', action='store', dest='local_dir',
                    help="Image on device location"),
    ])
    def do_img_activate(self, line, opts):
        """
        Activate an image update on device
        """
        device = self.get_device(depth=-1)
        device_id = device.id
        try:
            if device_id and opts.name and opts.local_dir:
                kw = dict(id=device_id)
                kw['name'] = opts.name
                kw['local_dir'] = opts.local_dir
            else:
                self.poutput('Device ID, Image Name, and Location are needed')
                raise Exception('Device ID, Image Name, and Location are needed')
        except Exception as e:
            self.poutput('Error activate image {}. Error:{}'.format(device_id, e))
            return
        kw['save_config'] = json.loads(opts.save_config.lower())
        self.poutput('activate image update {} {} {} {}'.format( \
                    kw['id'], kw['name'],
                    kw['local_dir'], kw['save_config']))
        response = None
        try:
            img_dnld = voltha_pb2.ImageDownload(**kw)
            stub = self.get_stub()
            img_dnld = stub.GetImageDownload(img_dnld)
            response = stub.ActivateImageUpdate(img_dnld)
        except Exception as e:
            self.poutput('Error activate image {}. Error:{}'.format(kw['id'], e))
            return
        name = enum2name(common_pb2.OperationResp,
                        'OperationReturnCode', response.code)
        self.poutput('response: {}'.format(name))
        self.poutput('{}'.format(response))

    @options([
        make_option('-n', '--name', action='store', dest='name',
                    help="Image name"),
        make_option('-s', '--save', action='store', dest='save_config',
                    help="Save Config", default="True"),
        make_option('-d', '--dir', action='store', dest='local_dir',
                    help="Image on device location"),
    ])
    def do_img_revert(self, line, opts):
        """
        Revert an image update on device
        """
        device = self.get_device(depth=-1)
        device_id = device.id
        try:
            if device_id and opts.name and opts.local_dir:
                kw = dict(id=device_id)
                kw['name'] = opts.name
                kw['local_dir'] = opts.local_dir
            else:
                self.poutput('Device ID, Image Name, and Location are needed')
                raise Exception('Device ID, Image Name, and Location are needed')
        except Exception as e:
            self.poutput('Error revert image {}. Error:{}'.format(device_id, e))
            return
        kw['save_config'] = json.loads(opts.save_config.lower())
        self.poutput('revert image update {} {} {} {}'.format( \
                    kw['id'], kw['name'],
                    kw['local_dir'], kw['save_config']))
        response = None
        try:
            img_dnld = voltha_pb2.ImageDownload(**kw)
            stub = self.get_stub()
            img_dnld = stub.GetImageDownload(img_dnld)
            response = stub.RevertImageUpdate(img_dnld)
        except Exception as e:
            self.poutput('Error revert image {}. Error:{}'.format(kw['id'], e))
            return
        name = enum2name(common_pb2.OperationResp,
                        'OperationReturnCode', response.code)
        self.poutput('response: {}'.format(name))
        self.poutput('{}'.format(response))
