#
# Copyright (c) 2011,2012,2013 Big Switch Networks, Inc.
#
# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
#
# 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.
#

import re
import numbers
import collections
import traceback
import types
import json
import time
import sys
import datetime
import os
import subprocess
import socket
import urllib2 # exception, dump_log()

import modi
import error
import command
import run_config
import rest_to_model
import url_cache

from midw import *
from vnsw import *
#from html5lib.constants import DataLossWarning

onos=1
#
# ACTION PROCS
#Format actions for stats per table
def remove_unicodes(actions):
   
    if actions:
        #TODO: Check:- Why I have to remove last two character from string
        #instead of 1 character to get rid of comma from last aciton
        a=''
        b=''
        newActions=''
        isRemoved_u = False
        for ch in actions:
            if ch =='u':
                a= 'u'
            if ch =='\'':
                b= '\''
                if isRemoved_u:
                    isRemoved_u=False
                    continue
                if (a+b) == 'u\'':
                    newActions = newActions[:-1]
                    a= ''
                    isRemoved_u = True
            else:
                newActions += ch
        return newActions
    else:
        ''
def renameActions(actions):
    actions = actions.replace('GOTO_TABLE','GOTO')
    actions = actions.replace('WRITE_ACTIONS','WRITE')
    actions = actions.replace('APPLY_ACTIONS','APPLY')
    actions = actions.replace('DEC_NW_TTL: True','DEC_NW_TTL')
    actions = actions.replace('POP_MPLS: True','POP_MPLS')
    actions = actions.replace('COPY_TTL_IN: True','COPY_TTL_IN')
    actions = actions.replace('COPY_TTL_OUT: True','COPY_TTL_OUT')
    actions = actions.replace('DEC_MPLS_TTL: True','DEC_MPLS_TTL')
    actions = actions.replace('SET_DL_SRC','SRC_MAC')
    actions = actions.replace('SET_DL_DST','DST_MAC')
    actions = actions.replace('SET_NW_SRC','SRC_IP')
    actions = actions.replace('SET_NW_DST','DST_IP')
    
    return actions

def check_rest_result(result, message=None):
    if isinstance(result, collections.Mapping):
        error_type = result.get('error_type')
        if error_type:
            raise error.CommandRestError(result, message)

tunnel_id=None
tunnel_dict={}
def tunnel_create(data=None):
    global tunnel_id,tunnel_dict
    if sdnsh.description:   # description debugging
        print "tunnel_create:" , data
    if data.has_key('tunnel-id'):
        if (tunnel_id != None):
            if sdnsh.description:   # description debugging
                print "tunnel_create: previous data is not cleaned up"
            tunnel_id=None
            tunnel_dict={}
        tunnel_id=data['tunnel-id']
        tunnel_dict[tunnel_id]=[]
    if data.has_key('node-label'):    
        tunnel_dict[tunnel_id].append(data['node-label'])
    if data.has_key('adjacency-label'):    
        tunnel_dict[tunnel_id].append(data['adjacency-label'])
    if sdnsh.description:   # description debugging
        print "tunnel_create:" , tunnel_id, tunnel_dict

def tunnel_config_exit():
    global tunnel_id,tunnel_dict
    if sdnsh.description:   # description debugging
        print "tunnel_config_exit entered", tunnel_dict
    if tunnel_dict:
        url_str = ""
        entries = tunnel_dict[tunnel_id]
        url_str = "http://%s/rest/v1/tunnel/" % (sdnsh.controller)
        obj_data = {}
        obj_data['tunnel_id']=tunnel_id
        obj_data['label_path']=entries
        result = "fail"
        try:
            result = sdnsh.store.rest_post_request(url_str,obj_data)
        except Exception, e:
            errors = sdnsh.rest_error_to_dict(e)
            print sdnsh.rest_error_dict_to_message(errors)
        # LOOK! successful stuff should be returned in json too.
        tunnel_dict = {}
        tunnel_id = None
        if result != "success":
            print "command failed"
    else:
        print "empty command"
    #Clear the transit information    
            
def tunnel_remove(data=None):
    if sdnsh.description:   # description debugging
        print "tunnel_remove:" , data
    tunnel_id=data['tunnel-id']
    url_str = "http://%s/rest/v1/tunnel/" % (sdnsh.controller)
    obj_data = {}
    obj_data['tunnel_id']=data['tunnel-id']
    result = "fail"
    try:
        result = sdnsh.store.rest_post_request(url_str,obj_data,'DELETE')
    except Exception, e:
        errors = sdnsh.rest_error_to_dict(e)
        print sdnsh.rest_error_dict_to_message(errors)
    if not result.startswith("SUCCESS"):
        print result

policy_obj_data = {}
def policy_create(data=None):
    global policy_obj_data
    if sdnsh.description:   # description debugging
        print "policy_create:" , data
    if data.has_key('policy-id'):
        if policy_obj_data:
            if sdnsh.description:   # description debugging
                print "policy_create: previous data is not cleaned up"
            policy_obj_data = {}
        policy_obj_data['policy_id'] = data['policy-id']
        policy_obj_data['policy_type'] = data['policy-type']
    if data.has_key('src_ip'):
        for key in data:
            policy_obj_data[key] = data[key]
    if data.has_key('priority'):
        policy_obj_data['priority'] = data['priority']
    if data.has_key('tunnel-id'):
        policy_obj_data['tunnel_id'] = data['tunnel-id']
    
    if sdnsh.description:   # description debugging
        print policy_obj_data
      
def policy_config_exit():
    global policy_obj_data
    if sdnsh.description:   # description debugging
        print "policy_config_exit entered", policy_obj_data
    if policy_obj_data:
        url_str = "http://%s/rest/v1/policy/" % (sdnsh.controller)
        result = "fail"
        try:
            result = sdnsh.store.rest_post_request(url_str,policy_obj_data)
        except Exception, e:
            errors = sdnsh.rest_error_to_dict(e)
            print sdnsh.rest_error_dict_to_message(errors)
        if result != "success":
            print "command failed"
        policy_obj_data = {}
    else:
        print "empty command"
    #Clear the transit information    
            
def policy_remove(data=None):
    if sdnsh.description:   # description debugging
        print "policy_remove:" , data
    policy_id=data['policy-id']
    url_str = "http://%s/rest/v1/policy/" % (sdnsh.controller)
    obj_data = {}
    obj_data['policy_id']=data['policy-id']
    result = "fail"
    try:
        result = sdnsh.store.rest_post_request(url_str,obj_data,'DELETE')
    except Exception, e:
        errors = sdnsh.rest_error_to_dict(e)
        print sdnsh.rest_error_dict_to_message(errors)
    if result != "deleted":
        print "command failed"
  
    

def write_fields(obj_type, obj_id, data):
    """
    Typical action to update fields of a row in the model

    @param obj_type a string, the name of the db table to update
    @param obj_id a string, the value of the primary key in for the table
    @param data a dict, the name:value pairs of data to update in the table
    """
    if sdnsh.description:   # description debugging
        print "write_fields:", obj_type, obj_id, data

    pk_name = mi.pk(obj_type)
    if not pk_name:
        raise error.CommandDescriptionError("Can't find primary key name for type: %s" % obj_type)
    if sdnsh.description:   # description debugging
        print "write_fields:", obj_type, pk_name, obj_id, data
    for fk in mi.obj_type_foreign_keys(obj_type):
        if fk in data and mi.is_null_allowed(obj_type, fk):
            if data[fk] == 'default': # XXX much too magic, seems an option here would be good
                data[fk] = None
            
    result = sdnsh.rest_update_object(obj_type, pk_name, obj_id, data)
    check_rest_result(result)


def verify_row_includes(obj_type, pk_value, data, verify):
    """
    Intended to raise an exception when a user enters 'no field value',
    and the field isn't currently set to value,  for example:
    'address-space as1 ; no address-space as2', should complain
    that the 'address-space' field isn't currently set to 'as2'.

    @param obj_type a string, identifies the db table
    @param pk_value a string, identifies the value for the primary key
    @param data is a dict, collecting the name:value pairs from the description
    @verify the string or list of field names to be verified
    """
    if sdnsh.description:   # description debugging
        print "validate_row_includes:", obj_type, pk_value, data, verify

    if type(verify) == str:
        verify = [verify] # if not a list, make it a list

    try:
        row = sdnsh.get_object_from_store(obj_type, pk_value)
    except Exception, e:
        if sdnsh.debug or sdnsh.debug_backtrace:
            print 'Failed lookup of %s:%s:%s', (obj_type, pk_value, e)
            traceback.print_exc()
        raise error.ArgumentValidationError("%s: '%s' doesn't exist" %
                                            (obj_type, pk_value))
        return
    
    if sdnsh.description:   # description debugging
        print "validate_includes: ", row
    for field in [x for x in verify if x in data and x in row]:
        if row[field] != data[field]:
            raise error.ArgumentValidationError("%s: %s found '%s' current value '%s'" %
                                                (obj_type, field, data[field], row[field]))


def reset_fields(obj_type, arg_data,
                 obj_id = None, fields = None, match_for_no = None):
    """
    For an obj_type, revert fields back to their default value.
    This is the typical action for 'no' commands.

    When verify is set, this is a string or list of fields who's values
    must match in the table for the primary key associated with the reset.
    This allows command descriptions to identify any fields which need to
    be checked against, when they are explicidly named in the 'no' command,
    so that 'no XXX value' will verify that 'value' matches the current 
    row's value before allowing the reset to continue

    @param obj_type a string, identifies the db table
    @param obj_id a string, identifies the value for the primary key of the row in the table,
            possibly unset, the key is looked for in the arg_data in that case.
    @param arg_data a dict, collection of name:value pairs from the description
    @param fields a list, collection of fields to update in the table
    @param match_for_no a string or list, list of fields to check for matched values in arg_data
    """

    if obj_type == None:
        raise error.CommandDescriptionError("No object to reset (missing obj-type)")
        
    pk_name = mi.pk(obj_type)
    # If the fields aren't specified explicitly, then derive from the arg_data
    if fields is None:
        fields = []
        for field in arg_data.keys():
            # Only add arguments that correspond to valid fields in the object
            if mi.obj_type_has_field(obj_type, field):
                if field != pk_name: # don't reset primary keys
                    fields.append(field)

    if len(fields) == 0:
        raise error.CommandDescriptionError("No fields to reset: type: %s" % obj_type)
 
    # Get the primary key name
    if not pk_name:
        raise error.CommandDescriptionError("Can't find primary key name for type: %s" % obj_type)
    if obj_id == None:
        if pk_name in arg_data:
            obj_id = arg_data[pk_name]
        elif mi.field_default_value(obj_type, pk_name):
            # unusual, but not impossible for singletons
            obj_id = mi.field_default_value(obj_type, pk_name)
        else:
            raise error.CommandDescriptionError("Can't find id value name for type: %s"
                                                " field %s" % (obj_type, pk_name))
    
    if match_for_no:
        verify_row_includes(obj_type, obj_id, arg_data, match_for_no)

    # Get the default values of the specified field from CLI model info
    data = {}
    for field in fields:
        if field == pk_name:
            continue
        type_info = mi.cli_model_info.get_field_info(obj_type, field)
        if type_info == None:
            raise error.CommandDescriptionError("Can't find field details for "
                                                "field %s in type %s" % (field, obj_type))
        data[field] = type_info.get('default')
        if data[field] == None and type_info.get('type') == 'BooleanField':
            data[field] = False
        # why does boolean not respect the default in the model?!?
        # data[field] = type_info.get('default') if type_info.get('type') != 'BooleanField' else False
    
    if sdnsh.description:   # description debugging
        print "reset_fields:", obj_type, pk_name, obj_id, data, match_for_no

    # Invoke the REST API to set the default values
    try:
        result = sdnsh.rest_update_object(obj_type, pk_name, obj_id, data)
    except Exception, e:
        errors = sdnsh.rest_error_to_dict(e, obj_type)
        raise error.CommandError('REST', sdnsh.rest_error_dict_to_message(errors))


def obj_type_fields_have_default_value(obj_type, row, data):
    """
    Return True when all the fields have a default value,
    row is the queried data from the store, 
    data is the data to be updated.

    The goal is to determine whether to delete or update
    the row in the store.

    """

    ckf = []
    if mi.is_compound_key(obj_type, mi.pk(obj_type)):
        # XXX primitive compound keys' too?
        ckf = mi.compound_key_fields(obj_type, mi.pk(obj_type))

    for field in mi.obj_type_fields(obj_type):
        if mi.is_primary_key(obj_type, field):
            continue
        if mi.is_foreign_key(obj_type, field):
            # perhaps only allow a single foreign key?
            continue
        # also any fields which are used to compound the ident.
        if field in ckf:
            continue
        # Needs a better way to identify non-model-fields
        if field == 'Idx':
            continue
        if mi.is_null_allowed(obj_type, field):
            # does this need to be more complex?
            if field in data and data[field] != None:
                return False
            continue # next field
        default_value = mi.field_default_value(obj_type, field)
        if default_value == None:
            if sdnsh.description:   # description debugging
                print 'default_value: no default: %s %s' % (obj_type, field)
            return False
        # check to see if the updated value would be the default
        if field in data and data[field] != default_value:
            if sdnsh.description:   # description debugging
                print 'default_value: not default %s %s %s' % \
                        (field, data[field], default_value)
            return False
        elif row.get(field, default_value) != default_value:
            if field in data and data[field] == default_value:
                if sdnsh.description:   # description debugging
                    print 'default_value: db not default %s %s %s' \
                          ' new value in data %s is default' % \
                            (field, row[field], default_value, data[field])
                continue
            if sdnsh.description:   # description debugging
                print 'default_value: db not default %s %s %s' % \
                        (field, row[field], default_value)
            return False
    return True


def update_config(obj_type, obj_id, data, no_command):
    """
    update_config is intended to write a row when the described data
    is different from the default values of the fields of  the row.

    When the data described in the call updates the field's values
    to all default values, the row associated with the obj_id is
    deleted. 

    This is intended to be used for models which contain configuration
    row data, and that every field has a default value,
    so that when the config data is transitioned to the default
    state, the row is intended to be removed.  For these sorts of
    command descriptions, updating a field to some default value
    may result in the row getting deleted.
    """

    c_data = dict(data)  # make a local copy
    if sdnsh.description:   # description debugging
        print "update_config: ", obj_type, obj_id, c_data, no_command
    
    if not mi.obj_type_exists(obj_type):
        raise error.CommandDescriptionError("Unknown obj-type: %s" % obj_type)
        
    # collect any dict.key names which aren't fields in the object
    for unknown_field in [x for x in c_data.keys() if not mi.obj_type_has_field(obj_type, x)]:
        del c_data[unknown_field]

    # if its a no command, set the value to 'None' if it's allowed,
    # of to its default value otherwise
    if no_command:
        for field in c_data.keys():
            if mi.is_null_allowed(obj_type, field):
                c_data[field] = None
            else:
                # required to have a default value
                c_data[field] = mi.field_default_value(obj_type, field)
            
    # Get the primary key name
    pk_name = mi.pk(obj_type)
    if not pk_name:
        raise error.CommandDescriptionError("Can't find primary key name for type: %s" % obj_type)
    pk_value = obj_id
    if pk_name in data:
        pk_value = data[pk_name]
    if pk_name in c_data:
        del c_data[pk_name]
    
    # Query for the row, if it doesn't exist, create the item if any item isn't default
    if sdnsh.description:   # description debugging
        print "update_config: query:", obj_type, pk_value

    result = sdnsh.rest_query_objects(obj_type, { pk_name : pk_value })
    check_rest_result(result)
    if len(result) == 0:
        # result[0] -> dictionary of field:value pairs
        # check to ensure c_data isn't just default row values
        if not obj_type_fields_have_default_value(obj_type, {}, c_data):
            if sdnsh.description:   # description debugging
                print "update_config: create:", obj_type, c_data
            # populate the create dictionary
            create_dict = dict(c_data)
            create_dict[pk_name] = pk_value
            result = sdnsh.rest_create_object(obj_type, create_dict)
            check_rest_result(result)
        else:
            if sdnsh.description:   # description debugging
                print "update_config: no current row"
        return
    else:
        if sdnsh.description:   # description debugging
            print "update_config: found row", result[0]

    if len(result) > 1:
        raise error.CommandInternalError("Multiple rows for obj-type: %s: pk %s" % 
                                           (obj_type, pk_value))

    # See if the complete row needs to be deleted.
    # For each of the current fields, if a field's default doesn't exist,
    # skip the row delete, or if any field has a non-default value, update
    # the requested fields instead of deleting the row.
    if obj_type_fields_have_default_value(obj_type, result[0], c_data):
        # if the table has foreign keys, check no children refer to this table.
        no_foreign_keys_active = True
        if obj_type in mi.foreign_key_xref:
            for (fk_obj_type, fk_fn) in mi.foreign_key_xref[obj_type][mi.pk(obj_type)]:
                try:
                    rows = sdnsh.get_table_from_store(fk_obj_type, fk_fn,
                                                      pk_value, "exact")
                except Exception, e:
                    rows = []
                if len(rows):
                    if sdnsh.description:   # description debugging
                        print "update_config: foreign key active:", \
                               fk_obj_type, fk_fn, pk_value
                    no_foreign_keys_active = False
                    break

        if no_foreign_keys_active:
            if sdnsh.description:   # description debugging
                print "update_config: delete:", obj_type, pk_value
            try:
                delete_result = sdnsh.rest_delete_objects(obj_type, { pk_name : pk_value })
                check_rest_result(delete_result)
            except Exception, e:
                errors = sdnsh.rest_error_to_dict(e)
                raise error.CommandInvocationError(sdnsh.rest_error_dict_to_message(errors))
            return
        # XXX if a row from some table is removed, and that table is using
        # foreign keys, then the table which is refered to ought to be
        # reviewed, to see if all the entries of the row which this table
        # refer's to are default, and if that parent table is a config-style
        # table, with all default values for every field, there's a good
        # argument that the row ought to be removed.
        
    # See if any of the c_data items in the matching row are different
    # (ie: is this update really necessary?)
    update_necessary = False
    for (name, value) in c_data.items():
        if name in result[0]:
            if value != result[0][name]:
                update_necessary = True
                if sdnsh.description:   # description debugging
                    print "update_config: update necessary:", name, result[0][name], value
        else:
            update_necessary = True

    if not update_necessary:
        if sdnsh.description:   # description debugging
            print "update_config: no update needed", obj_type, pk_name, pk_value
        return

    if sdnsh.description:   # description debugging
        print "update_config: update:", obj_type, pk_name, pk_value, c_data
    # Invoke the REST API to set the default values
    result = sdnsh.rest_update_object(obj_type, pk_name, pk_value, c_data)
    check_rest_result(result)


def delete_objects(obj_type, data, parent_field=None, parent_id=None):
    """
    Delete a row in the table.

    @param obj_type a string, the name of the table to update
    @param data a dictionary, name:value pairs to describe the delete
    @param parent_field a string, the name of a field in the obj_type,
            identifying a relationship between this table, and another table
    @param parent_id a string, the value of the parent_field, to identify
            another row in the other table identified by a field in this table
    """

    pk_name = mi.pk(obj_type)
    if not pk_name:
        raise error.CommandDescriptionError("Can't find primary key name for type: %s" % obj_type)

    query_data = dict(data)
    if parent_field:
        query_data[parent_field] = parent_id

    # case conversion
    for field in data:
        if mi.obj_type_has_field(obj_type, field):
            case = mi.get_obj_type_field_case_sensitive(obj_type, field)
            if case:
                if sdnsh.description:   # description debugging
                    print 'delete_objects: case convert %s:%s to %s' % \
                          (obj_type, field, case)
                data[field] = utif.convert_case(case, data[field])

    query_result = sdnsh.rest_query_objects(obj_type, query_data)
    check_rest_result(query_result)
    #
    # if there were no results, try to delete by removing any
    # items which have "None" values
    if len(query_result) == 0:
        for key in query_data.keys():
            if query_data[key] == None:
                del query_data[key]
        query_result = sdnsh.rest_query_objects(obj_type, query_data)
        check_rest_result(query_result)

    if sdnsh.description:   # description debugging
        print "delete_objects:", obj_type, query_data
    delete_result = sdnsh.rest_delete_objects(obj_type, query_data)
    check_rest_result(delete_result)

    for item in query_result:
        key = item[pk_name]
        sdnsh.cascade_delete(obj_type, key)


def set_data(data, key, value):
    """
    Action to associate a new name:value pair with 'data', the dictionary used 
    to pass to REST API's.   Allows the action to describe a value for a field
    which wasn't directly named in the description.

    """
    if sdnsh.description:   # description debugging
        print "set_data:", data, key, value
    data[key] = value


def write_object(obj_type, data, parent_field=None, parent_id=None):
    """
    Write a new row into a specific table.

    """
    # If we're pushing a config submode with an object, then we need to extend the
    # argument data that was entered explicitly in the command with the information
    # about the parent object (by default obtained by looking at the obj info on
    # the mode stack -- see default arguments for this action when it is added).

    if sdnsh.description:   # description debugging
        print 'write_object: params ', obj_type, data, parent_field, parent_id
    data = dict(data) # data is overwriten in various situations below
    if parent_field:
        if not parent_id:
            raise error.CommandDescriptionError('Invalid command description;'
                                              'improperly configured parent info for create-object')
        data[parent_field] = parent_id

    pk_name = mi.pk(obj_type)
    if not pk_name:
        raise error.CommandDescriptionError("Can't find primary key name for type: %s" % obj_type)

    # look for unpopulated foreign keys.
    fks = mi.obj_type_foreign_keys(obj_type)
    if fks:
        for fk in fks:
            (fk_obj, fk_nm) = mi.foreign_key_references(obj_type, fk)
                
            if not fk in data or \
               (mi.is_compound_key(fk_obj, fk_nm) and data[fk].find('|') == -1):
                # use various techniques to populate the foreign key
                # - if the foreign key is for class which has a compound key, see if all the
                #   parts of the compound key are present

                if mi.is_compound_key(fk_obj, fk_nm):
                    kfs = mi.deep_compound_key_fields(fk_obj, fk_nm)
                    missing = [x for x in kfs if not x in data]
                    if len(missing) == 0:
                        # remove the entries, build the compound key for the foreign key reference
                        new_value = mi.compound_key_separator(fk_obj, fk_nm).\
                                          join([data[x] for x in kfs])
                        # verify the foreign key exists, if not complain and return,
                        # preventing a error during the create request
                        query_result = sdnsh.rest_query_objects( fk_obj, { fk_nm : new_value })
                        check_rest_result(query_result)
                        if len(query_result) == 0:
                            joinable_name = ["%s: %s" % (x, data[x]) for x in kfs]
                            raise error.CommandSemanticError("Reference to non-existant object: %s " %
                                                               ', '.join(joinable_name))
                        for rfn in kfs: # remove field name
                            del data[rfn]
                        data[fk] = new_value
                else:
                    qr = sdnsh.rest_query_objects(fk_obj, data)
                    if len(qr) == 1:
                        data[fk] = qr[0][mi.pk(fk_obj)]

    if pk_name in data:
        if sdnsh.description:   # description debugging
            print command._line(), 'write_object: query pk_name ', obj_type, pk_name, data
        case =  mi.get_obj_type_field_case_sensitive(obj_type, pk_name)
        if case:
            data[pk_name] = utif.convert_case(case, data[pk_name])
        query_result = sdnsh.rest_query_objects(obj_type, { pk_name : data[pk_name]})
    else:
        query_data = dict([[n,v] for (n,v) in data.items() if v != None])
        if sdnsh.description:   # description debugging
            print command._line(), 'write_object: query ', obj_type, query_data
        query_result = sdnsh.rest_query_objects(obj_type, query_data)
    check_rest_result(query_result)
 
    # Consider checking to see if all the fields listed here
    # already match a queried result, if so, no write is needed

    if (len(query_result) > 0) and (pk_name in data):
        if sdnsh.description:   # description debugging
            print "write_object: update object", obj_type, pk_name, data
        result = sdnsh.rest_update_object(obj_type, pk_name, data[pk_name], data)
    else:
        if sdnsh.description:   # description debugging
            print "write_object: create_object", obj_type, data
        result = sdnsh.rest_create_object(obj_type, data)
        
    check_rest_result(result)

    for item in query_result:
        key = item[pk_name]
        sdnsh.cascade_delete(obj_type, key)


def delete_object(obj_type, data, parent_field=None, parent_id=None):
    global sdnsh

    data = dict(data)
    if parent_field:
        if not parent_id:
            raise error.CommandDescriptionError('Invalid command description;'
                            'improperly configured parent info for delete-object')
        data[parent_field] = parent_id

    # case conversion
    for field in data:
        if mi.obj_type_has_field(obj_type, field):
            case = mi.get_obj_type_field_case_sensitive(obj_type, field)
            if case:
                if sdnsh.description:   # description debugging
                    print 'delete_object: case convert %s:%s to %s' % \
                          (obj_type, field, case)
                data[field] = utif.convert_case(case, data[field])

    if sdnsh.description:   # description debugging
        print "delete_object: ", obj_type, data
    result = sdnsh.rest_delete_objects(obj_type, data)
    check_rest_result(result)


def push_mode_stack(mode_name, obj_type, data, parent_field = None, parent_id = None, create=True):
    """
    Push a submode on the config stack.
    """
    global sdnsh, modi

    # Some few minor validations: enable only in login, config only in enable,
    # and additional config modes must also have the same prefix as the
    # current mode.
    current_mode = sdnsh.current_mode()

    if sdnsh.description:   # description debugging
        print "push_mode: ", mode_name, obj_type, data, parent_field, parent_id

    # See if this is a nested submode, or whether some current modes
    # need to be popped.
    if (mode_name.startswith('config-') and 
      (not mode_name.startswith(current_mode) or (mode_name == current_mode))):

        sdnsh.pop_mode()
        current_mode = sdnsh.current_mode()
        # pop until it it matches
        while not mode_name.startswith(current_mode):
            if len(sdnsh.mode_stack) == 0:
                raise error.CommandSemanticError('%s not valid within %s mode' %
                                           (mode_name, current_mode))
            sdnsh.pop_mode()
            current_mode = sdnsh.current_mode()

        # if there's a parent id, it is typically the parent, and audit
        # ought to be done to verify this
        if parent_field:
            data = dict(data)
            data[parent_field] = sdnsh.get_current_mode_obj()

    elif mode_name in ['config', 'enable', 'login']:
        # see if the mode is in the stack
        if mode_name in [x['mode_name'] for x in sdnsh.mode_stack]:
            if sdnsh.description:   # description debugging
                print 'push_mode: popping stack for', mode_name
            current_mode = sdnsh.current_mode()
            while current_mode != mode_name:
                sdnsh.pop_mode()
                current_mode = sdnsh.current_mode()
            return


    # If we're pushing a config submode with an object, then we need to extend the
    # argument data that was entered explicitly in the command with the information
    # about the parent object (by default obtained by looking at the obj info on
    # the mode stack -- see default arguments for this action when it is added).
    elif parent_field:
        if not parent_id:
            raise error.CommandDescriptionError('Invalid command description; '
                                          'improperly configured parent info for push-mode-stack')
        data = dict(data)
        data[parent_field] = parent_id
        
    key = None
    if obj_type:
        for field in data:
            if mi.obj_type_has_field(obj_type, field):
                case = mi.get_obj_type_field_case_sensitive(obj_type, field)
                if case:
                    if sdnsh.description:   # description debugging
                        print 'push_mode: case convert %s:%s to %s' % \
                              (obj_type, field, case)
                    data[field] = utif.convert_case(case, data[field])


        # Query for the object both to see if it exists and also to determine
        # the pk value we're going to push on the stack. We need to do
        # the query in the case where the model uses compound keys and we're
        # specifying the individual fields that compose the compound key.
        result = sdnsh.rest_query_objects(obj_type, data)
        check_rest_result(result)
        if len(result) == 0 and create:
            #
            # For vns-interface, the association of 'rule' with the data dict
            # is difficult to explain via the command description.  This is
            # obviously a poor method of dealing with the issue, but until
            # a better one arises (possibly REST api create?  possibly
            # model validation code?), this solution works.
            if obj_type == 'vns-interface':
                data = associate_foreign_key_for_vns_interface(data)

            # Create the object and re-query to get the id/pk value
            # FIXME: Could probably optimize here if the data already
            # contains the pk value.
            if sdnsh.description:   # description debugging
                print "push_mode: create ", obj_type, data
            result = sdnsh.rest_create_object(obj_type, data)
            check_rest_result(result)
            result = sdnsh.rest_query_objects(obj_type, data)
            check_rest_result(result)
        else:
            if sdnsh.description:   # description debugging
                print "push_mode: object found", obj_type, result
        
        # Check (again) to make sure that we have an object
        if len(result) == 0:
            raise error.CommandSemanticError('Object not found; type = %s' % obj_type)
        
        # Check to make sure there aren't multiple matching objects. If there
        # are that would indicate a problem in the command description.
        if len(result) > 1:
            raise error.CommandDescriptionError('Push mode info must identify a single object;'
                                          'type = %s; data = %s'  %
                                          (obj_type, str(data)))
        
        # Get the id/pk value from the object info
        pk_name = mi.pk(obj_type)
        if not pk_name:
            raise error.CommandDescriptionError("Can't find primary key name for type: %s" % obj_type)
        key = result[0][pk_name]
    else:
        pk_name = '<none>'
    
    if sdnsh.description:   # description debugging
        print "push_mode: ", mode_name, obj_type, pk_name, key
    exitCallback = None
    if (mode_name == 'config-tunnel'):
        exitCallback = tunnel_config_exit
    if (mode_name == 'config-policy'):
        exitCallback = policy_config_exit
    sdnsh.push_mode(mode_name, obj_type, key, exitCallback)

    
def pop_mode_stack():
    global sdnsh

    if sdnsh.description:   # description debugging
        print "pop_mode: "
    sdnsh.pop_mode()

def confirm_request(prompt):
    global sdnsh

    if sdnsh.batch:
        return
    result = raw_input(prompt)
    if result.lower() == 'y' or result.lower() == 'yes':
        return
    raise error.ArgumentValidationError("Expected y or yes, command: ")

import c_data_handlers

def convert_vns_access_list(obj_type, key, data):
    """
    For vns-access-group's, the access list which is the first parameter
    needs to be converted into a vns-access-list foreign key.  This is
    possible since the vns name is part of the current object id.
    """
    global sdnsh, modi

    key_parts = key.split('|')
    if len(key_parts) != 3:
        raise error.ArgumentValidationError("invalid id")
    if not 'vns-access-list' in data:
        raise error.ArgumentValidationError("missing vns-access-list")
    try:
        key_parts.pop()
        vnskey='|'.join(key_parts)
        entry = sdnsh.rest_query_objects('vns-access-list',
                                        { 'vns' : vnskey,
                                          'name' : data['vns-access-list']
                                        })
    except Exception, _e:
        entry = []

    if len(entry) != 1:
        raise error.ArgumentValidationError("unknown acl %s" % data['vns-access-list'])
    data['vns-access-list'] = entry[0]['id']
          
def command_query_object(obj_type, data, scoped, sort):
    """
    Return model entries (db rows) via the REST API.  Try to be
    very smart about using parameters and the model definition to
    figure out how to query for the entries.
    """

    if sdnsh.description:
        print 'command_query_object: ', obj_type, data, scoped, sort
        
    skipforeignsearch=False
    if (obj_type=='virtualrouter-routingrule' or obj_type=='virtualrouter-interface'):
        skipforeignsearch=True
    # big_search describes a related search which must be done to
    # satisfy this request, see the relationship of tag-mapping to tag
    # as an example.
    big_search = []

    key = mi.pk(obj_type)
    #
    if mi.is_compound_key(obj_type, key):
        if sdnsh.description:   # description debugging
            print "command_query_object: %s compound %s" % (obj_type, key)
        #
        # collect compound key names, look for these in the data,
        # if any of the values are 'all', remove the item from
        # the group of data.
        #
        # XXX needs work: we ought to check to see if the
        # compound key is part of some other key.
        #
        if scoped:
            obj_d = { key : sdnsh.get_current_mode_obj() }
            mi.split_compound_into_dict(obj_type, key, obj_d, is_prefix = True)
            for (k,v) in obj_d.items():
                if k != key and not k in data:
                    data[k] = v

        new_data = {}
        dckfs = mi.deep_compound_key_fields(obj_type, key)
        if key in data:
            mi.split_compound_into_dict(obj_type, key, data, is_prefix = True)
        foreign_obj_type_search = {}
        
        for kf in dckfs:
            if mi.obj_type_has_field(obj_type, kf) and kf in data and data[kf] != 'all':
                new_data[kf] = data[kf]
            elif not mi.obj_type_has_field(obj_type, kf):
                # deep_compound_keys returns references via foreign keys.
                # if the field is missing in obj_type, its likely from
                # some related fk.
                for fk in mi.obj_type_foreign_keys(obj_type):
                    (_fk_obj_type, fk_name) = mi.foreign_key_references(obj_type,
                                                                        fk)
                    if kf == fk_name:
                        # print "FOUND MATCH ", kf, _fk_obj_type, fk_name
                        continue
                    elif not mi.is_compound_key( _fk_obj_type, fk_name):
                        continue
                    for fkcf in mi.compound_key_fields(_fk_obj_type, fk_name):
                        if fkcf in data and data[fkcf] != 'all':
                            # assume all models use COMPOUND_KEY_FIELDS
                            if _fk_obj_type not in foreign_obj_type_search:
                                foreign_obj_type_search[_fk_obj_type] = {}
                            foreign_obj_type_search[_fk_obj_type][fkcf] = data[fkcf]
                pass
            # see if foreign key fields are indirectly named
            elif mi.is_foreign_key(obj_type, kf):
                (_fk_obj_type, fk_name) = mi.foreign_key_references(obj_type,
                                                                    kf)
                if fk_name in data and data[fk_name] != 'all':
                    new_data[kf] = data[fk_name]
        if (not skipforeignsearch): #skip foreign key search for routingrule type
            if len(foreign_obj_type_search):
                # This means to collect the entries, a search though a
                # related obj_type (through foreign key) will need to be done
                # a single query isn't enough, unless all entries are collected
                # consider the relationship between tag-mapping and tags
                # 
                # This code seems to handle single indirected foreign key
                # lookup, but if deep_compound_key_fields() found more than
                # three layers deep (the obj-type has a fk reference to a
                # table, which had a fk reference to another table, which
                # had a value to search with), this won't do the trick.
                # at that point some sort of recursive building of the
                # foreign keys would be needed to collect up the required
                # final seraches
                for (_fk_obj_type, search) in foreign_obj_type_search.items():
                    fk_entries = sdnsh.rest_query_objects(_fk_obj_type, search)
                    # need to identify the name associated foreign key in this model
                    for fk in mi.obj_type_foreign_keys(obj_type):
                        (fk_obj, fk_name) = mi.foreign_key_references(obj_type, fk)
                        if fk_obj == _fk_obj_type:
                            obj_type_field = fk
                            break
                    else:
                        raise error.CommandSemanticError("bigsearch: can't find fk reference"
                                                         "for %s for obj-type %s" %
                                                         (fk, obj_type))
                    big_search += [{obj_type_field:
                                    x[mi.pk(_fk_obj_type)]} for x in fk_entries]
                # big_search would return id's for the _fk_obj_type,
                # which can be used to search this obj_type
        # look for fields which are set in new_data, which aren't in data.
        for (field, value) in data.items():
            if field not in new_data:
                if mi.is_marked_searchable(obj_type, field) and value!='all':
                    new_data[field] = value

        data = new_data
    else:
        # Only allow fields which are searchable (XXX need a prediate)
        # only save primary key's and foreigh keys.
        new_data = {}
        if key in data and mi.is_primary_key(obj_type, key):
            new_data[key] = data[key]
        for fk in mi.obj_type_foreign_keys(obj_type):
            if fk in data:
                new_data[fk] = data[fk]
            (_fk_obj, fk_fn) = mi.foreign_key_references(obj_type, fk)
            if fk_fn in data:
                new_data[fk_fn] = data[fk_fn]
        for f in mi.obj_type_fields(obj_type):
            if f in data and f not in new_data:
                new_data[f] = data[f]
            
        data = new_data

        if scoped:
            data[key] = sdnsh.get_current_mode_obj()
        
    if key in data and (data[key]=='all' or data[key]==None):
        del data[key]
    #
    # Now that the fields have been disassembled as much as possible, see
    # if some of the entries need to be cobbled back together.
    fks = mi.obj_type_foreign_keys(obj_type)
    if sdnsh.description:   # description debugging
        print "command_query_object: %s foreign-key %s" % (obj_type, fks)
    if fks:
        for fk in fks:
            (fk_obj, fk_nm) = mi.foreign_key_references(obj_type, fk)
                
            if not fk in data or \
               (mi.is_compound_key(fk_obj, fk_nm) and data[fk].find('|') == -1):

                # use various techniques to populate the foreign key
                # - if the foreign key is for class which has a compound key, see if all the
                #   parts of the compound key are present
                if mi.is_compound_key(fk_obj, fk_nm):
                    kfs = mi.deep_compound_key_fields(fk_obj, fk_nm)
                    missing = [x for x in kfs if not x in data]
                    if len(missing) == 0:
                        # remove the entries, build the compound key for the foreign key reference
                        new_value = mi.compound_key_separator(fk_obj, fk_nm).\
                                          join([data[x] for x in kfs])
                        # verify the foreign key exists, if not complain and return,
                        # preventing a error during the create request
                        query_result = sdnsh.rest_query_objects( fk_obj, { fk_nm : new_value })
                        check_rest_result(query_result)
                        if len(query_result) == 0:
                            joinable_name = ["%s: %s" % (x, data[x]) for x in kfs]
                            raise error.CommandSemanticError("Reference to non-existant object: %s " %
                                                               ', '.join(joinable_name))
                        for rfn in kfs: # remove field name
                            del data[rfn]
                        data[fk] = new_value
        if sdnsh.description:   # description debugging
            print "command_query_object: %s foreign key construction " % obj_type, data
    #
    # Do something for alias displays, for obj_types which sdnsh says
    # are aliases, find the foreign reference in the alias obj_type,
    # and use that to determine the field name (fk_fn) in the parent.
    # Do lookups based on either the alias field name, or the parent's
    # fk_fn when set in data{}
    if obj_type in mi.alias_obj_types:
        field = mi.alias_obj_type_field(obj_type)
        (_fk_obj, fk_fn) = mi.foreign_key_references(obj_type, field)
        new_data = {}
        if fk_fn in data and data[fk_fn] != 'all':
            new_data[field] = data[fk_fn]
        elif field in data and data[field] != 'all':
            new_data[field] = data[field]
        data = new_data

    #
    # The sort value ought to be a command separated list of fields within the model
    #
    if sort:
        data['orderby'] = sort

    if not mi.obj_type_has_model(obj_type):
        return rest_to_model.get_model_from_url(obj_type, data)

    if sdnsh.description:   # description debugging
        print "command_query_object: ", obj_type, data

    if len(big_search):
        entries = []
        if sdnsh.description:   # description debugging
            print "command_query_object: big search", big_search
        for bs in big_search:
            search = dict(list(bs.items()) + list(data.items()))
            entries += sdnsh.rest_query_objects(obj_type, search)
        # XXX needs to be re-sorted
        return entries
        
    return sdnsh.rest_query_objects(obj_type, data)


def command_display_table_join_entries(obj_type, data, entries, detail):
    """
    """
    if obj_type == 'tag-mapping':
        # lift persist from the parent tag
        if len(entries) == 1:
            entry = entries[0]
            tag = sdnsh.rest_query_objects('tag', { mi.pk('tag') : entry['tag']})
            entry['persist'] = tag[0]['persist']
        else:
            # key? value? for the _dict?
            tags = create_obj_type_dict('tag', mi.pk('tag'))
            for entry in entries:
                entry['persist'] = tags[entry['tag']][0]['persist']

    if obj_type == 'controller-node':
        # This is a big odd, since the current node needs to be asked
        # which controller node it is
        url = "http://%s/rest/v1/system/controller" % sdnsh.controller

        result = sdnsh.store.rest_simple_request(url)
        check_rest_result(result)
        iam = json.loads(result)

        cluster_url = ("http://%s/rest/v1/system/ha/clustername"
                       % sdnsh.controller)
        result = sdnsh.store.rest_simple_request(cluster_url)
        check_rest_result(result)
        # perhaps ought to assert on lenresult) == 1
        clustername = json.loads(result)[0]['clustername']

        for entry in entries:
            controller = None
            if entry['id'] == iam['id']:
                controller = sdnsh.controller
            else:
                # find interfaces which hacve a firewall rule open for
                # tcp/80.  ie: ip for the interface with rest-api role
                ips = local_interfaces_firewall_open("tcp", 80, entry)

                # controller-interfaces needs to be examined to determine
                # if there's an ip address to use to discover the ha-role
                if len(ips) == 1:
                    # Not even certain if this is reachable
                    if ips[0]['discovered-ip'] != '':
                        controller = ips[0]['discovered-ip']
                    elif ips[0]['ip'] != '':
                        controller = ips[0]['ip']
                    else:
                        entry['ha-role'] = 'no-ip'
                        entry['errors'] = 'No IP Address'
                else:
                    entry['errors'] = 'No IP Address'

            if controller == None:
                entry['errors'] = 'No ip address configured'
                entry['ha-role'] = 'unknown'
                continue

            try:
                url = "http://%s/rest/v1/system/ha/role" % controller
                result = sdnsh.store.rest_simple_request(url, timeout = 2)
                check_rest_result(result)
                ha_role = json.loads(result)
                entry['ha-role'] = ha_role['role']
                if not 'clustername' in ha_role:
                    entry['errors'] = 'no clustername in ha-role rest api'
                    entry['ha-role'] = 'Untrusted: %s' % ha_role['role']
                elif ha_role['clustername'] != clustername:
                    entry['errors'] = 'Not in HA Cluster, requires decomission'
                    entry['ha-role'] = 'External Cluster: %s' % ha_role['role']
                if 'change-date-time' in ha_role:
                    entry['change-date-time'] = ha_role['change-date-time']
                if 'change-description' in ha_role:
                    entry['change-description'] = ha_role['change-description']
            except urllib2.HTTPError, e: # timeout?
                entry['errors'] = e.reason
                entry['ha-role'] = 'unknown'
                continue
            except urllib2.URLError, e: # timeout?
                entry['errors'] = '%s: %s' % (controller, e.reason)
                entry['ha-role'] = 'unknown'
                continue # dontt try the uptime, it will fail too
            except Exception, e:
                entry['errors'] = str(e)
                entry['ha-role'] = 'unknown'

            url = "http://%s/rest/v1/system/uptime" % controller
            try:
                result = sdnsh.store.rest_simple_request(url)
                check_rest_result(result)
                uptime = json.loads(result)
                entry['uptime'] = uptime['systemUptimeMsec']

            except Exception, e:
                pass

    return detail


def command_display_table(obj_type, data, detail = 'default',
                          table_format = None, title = None, scoped = None, sort = None):

    """
    Display entries from a obj_type, with some filtering done via data,
    and the output format described by table_format, with the devel of detail in detail

    @param obj_type string name of the object type
    @param data dictionary of configured data items from the description
    @param table_format string describing table format to use for output
    @param detail string describing the detail-flavor for format
    @param scoped string, when not null, indicates the submode level is used to filter query request
    @param sort string, describes sort to append to the query request
    """

    if not mi.obj_type_exists(obj_type):
        raise error.CommandDescriptionError("Unknown obj-type: %s" % obj_type)
        
    if sdnsh.description:   # description debugging
        print "command_display_table:", obj_type, data, table_format, detail, scoped, sort

    if 'detail' in data:
        detail = data['detail']

    if not table_format:
        if 'format' in data:
            table_format = data['format']
        else:
            table_format = obj_type
    if 'scoped' in data:
        scoped=data['scoped']
        del data['scoped']
    entries = command_query_object(obj_type, data, scoped, sort)
    if sdnsh.description:   # description debugging
        print "command_display_table: %d entries found, using %s" % (len(entries), data)

    # update any of the pretty-printer tables based on the obj_type
    obj_type_show_alias_update(obj_type)

    # with_key manages whether a 'detail' or table is displayed.
    with_key = '<with_key>' if detail == 'details' and len(entries) > 0 else '<no_key>'

    # pick foreign keys which are compound keys, explode these into fields
    fks = [x for x in mi.obj_type_foreign_keys(obj_type) if mi.is_compound_key(obj_type,x)]
    for entry in entries:
        for fk in fks:
            if fk in entry: # fk may be null-able
                mi.split_compound_into_dict(obj_type, fk, entry, True)
    #
    detail = command_display_table_join_entries(obj_type, data, entries, detail)

    # use display_obj_type_rows since it (currently) joins fields for obj_types.
    display = sdnsh.display_obj_type_rows(table_format, entries, with_key, detail)
    if title:
        return title + display
    return display


def command_display_rest_join_entries(table_format, data, entries, detail):
    """
    @param table_format string, identifying the final table output
    @param data   dict, used to query the rest api output
    @param entries list of dicts, ready to be displayed
    @return string replacing detail

    """

    if sdnsh.description:   # description debugging
        print "command_display_rest_join_entries: ", table_format, data, detail
        
    if table_format == 'controller-interface':
        # join firewall rules for these interfaces
        for intf in entries:
            rules = [x['rule'] for x in sdnsh.get_firewall_rules(intf['id'])]
            intf['firewall'] = ', '.join(rules)

    if table_format == 'system-clock':
        # join the 'time' string, possibly remove 'tz' from entries[0]
        entries[0]['time'] = sdnsh.get_clock_string(entries[0], data.get('detail'))
        return 'details' # force table format

    return detail


def command_display_rest_type_converter(table_format, rest_type, data, entries):
    """
    the expected display table_format is a list of dictionaries
    each dictionary has the field : value pairs.  Many rest api's
    return a dictionary of different layers, the description
    provides a rest-type, which is used to describe the form
    of the value returned from the rest api.
    """

    if sdnsh.description:   # description debugging
        print "command_display_rest_type_converter: ", table_format, rest_type
        
    if rest_type.startswith('dict-of-list-of-'):
        # entries look like { row_name : [value, ...], ... more-row-value-pairs }
        #
        # dict-of-list-of: a dict with key's which are given
        # the name of the first token, then the dict's value is
        # a list which can be given an associated name.
        # for example 'dict-of-list-of-cluster-id|[switches]'
        #
        # 'dict-of-list-of-switch' is a dict with key : value's
        # where the value is a list.  The member's of the list
        # are dictionaries.  the key of the outer dict is added to
        # each of the dicts, and this interior dict is added to
        # the final output list.

        # identify the added key from the rest_type
        key = rest_type.replace('dict-of-list-of-','')
        parts = key.split('|')
        names = None
        build_list = False
        if len(parts) > 0:
            key = parts[0]
            names = parts[1:] # should only be one name
            if len(names) > 0 and names[0][0] == '[':
                build_list = True
        formatted_list = []
        for (row_name, rows) in entries.items():
            if not rows:
                continue
            # use the names as ways of describing each of the list's items
            if type(rows) == list and build_list:
                # name[0] looks like '[switches]', requesting that this
                # list become switches : [rows] 
                formatted_list.append({key : row_name, names[0][1:-1] : rows})
            elif type(rows) == list:
                for row in rows:
                    add_dict = {key : row_name}
                    if type(row) == str or type(row) == unicode:
                        add_dict[names[0]] = row
                    elif type(row) == dict:
                        # addition names make no difference
                        add_dict.update(row)
                    formatted_list.append(add_dict)
            elif type(rows) == dict:
                do_append = True
                new_row = { key : row_name }
                for name in [x for x in names.keys() if x in row]:
                    item = row[name]
                    if type(item) == str or type(item) == unicode:
                        new_row[name] = item
                    if type(item) == dict:
                        new_row[name].update(item)
                    if type(item) == list:
                        do_append = False
                        for i_row in item:
                            new_row.update(i_row)
                            formatted_list.append(new_row)
                            new_row = { key : row_name }
                if do_append:
                    formatted_list.append(new_row)

        entries = formatted_list
    elif rest_type.startswith('dict-of-dict-of-'):
        # entries looks like { row_name : { [ { }, ... ] }  }
        #                                      ^
        #                            want this |
        # ie: dict with a value which is a dict, whose
        # 'dict-of-dict-of-switch|ports'  The dict has key : values
        # where the value is a dict.  That dict has the 'switch' : key
        # added, and it becomes the final output dict.
        #
        # if a second name is included, then the outer dict is 
        # examined to find these values (ie: values[names]), and these
        # get added to the final output dict.
        # 
        # identify the added key from the rest_type
        key = rest_type.replace('dict-of-dict-of-','')
        parts = key.split('|')
        name = None
        if len(parts) > 0:
            names = parts[1:]
            key = parts[0]
        formatted_list = []
        for (row_name, row) in entries.items():
            row[key] = row_name
            do_append = False
            if names:
                new_row = {}
                for name in names:
                    if name in row:
                        item = row[name]
                        if type(item) == str or type(item) == unicode:
                            new_row[name] = item
                            do_append = True
                        elif type(item) == dict:
                            if name == row_name:
                                do_append = True
                        elif type(item) == list:
                            for i_row in item:
                                row_items = {}
                                row_items[key] = row_name
                                row_items.update(i_row)
                                formatted_list.append(row_items)
                if do_append:
                    formatted_list.append(row)
                    
            else:
                formatted_list.append(row)
                                
        entries = formatted_list
    elif rest_type.startswith('dict-with-'):
        # rest result looks like: { k : v, k : { } }
        #                                       ^
        #                             want this |
        # dict-with: typically used for dict returns which have
        # nested dict's who's values are promoted to a single
        # list with a dict with these values.
        #
        # identify the added key from the rest_type
        key = rest_type.replace('dict-with-','')
        names = key.split('|')
        collect_row = {}
        formatted_list = []
        for name in names:
            if name in entries:
                item = entries[name]
                if type(item) == str or type(item) == unicode or \
                  type(item) == int or type(item) == long: # XXX float?
                    collect_row[name] = item
                elif type(item) == list:
                    for i_row in item:
                        row_items = {}
                        formatted_list.append(i_row)
                elif type(item) == dict:
                    collect_row.update(item)

        if len(collect_row) == 0:
            entries = formatted_list
        else:
            entries = [collect_row] + formatted_list

    elif rest_type == 'dict':
        entries = [entries]
    else:
        raise error.CommandDescriptionError("Unknown rest-type: %s" % rest_type)
    return entries


def missing_part(key_parts, entry, key_case = False):
    """
    Return the name of the missing field of one of the strings
    in the key_parts list when it  doesn't appear in the 'entry' dictionary.

    Return None otherwise.

    This is used to identify rows which don't have all the
    parts needed to constrcut a join key, or a db-table or
    query "key" to support addition of two different tables.

    @key_parts list of strings, 
    @entry dictionary, needs to contains each string in key_parts
    @key_case True when all key_parts may contain a leading '~' to
        denote the field needs to be lower cased for joining
    """
    for kn in key_parts:
        if not kn in entry:
            if key_case == False:
                return kn
            if kn[0] != '~':
                return kn
            if kn[1:] not in entry:
                return kn[1:]

    return None


def case_cvt(fn, f_dict):
    """
    For join operations, the fields in the partial result can no longer
    be associated with any obj-type, which means its impossible to determine
    whether the associated field is case sensitive.

    One approach to this problem is to case-normalize the obj-type's
    field values when they're first added to the row.   That doesn't
    help for rest-api's, which means it can only be a partial solution.
    In addition, it makes sense to preserve these values when possible,
    but still join based on case-normalization.
    """
    if fn[0] == '~':
        return str(f_dict.get(fn[1:], '').lower())
    return str(f_dict.get(fn, ''))


def obj_type_field_case(data, obj_type, field):
    """
    For objects where the case-normalization is identifed,
    manage conversion of the value associated with the field
    """
    case = mi.get_obj_type_field_case_sensitive(obj_type, field)
    return str(data[field]) if not case else str(utif.convert_case(case, data[field]))


def add_fields(dest, src):
    """
    These should both be dictionaries, leave the original entries in place
    when the 'dest' entries are populated from 'src'.   This operation is
    handy since the original 'dest' entries may differ from the 'src' due
    to case normalization.   Since having consistent names is a plus, by
    not updating the value with the 'src' entries, 'dest' retains its original
    values.
    """
    for (n,v) in src.items():
        if n not in dest:
            dest[n] = v
        elif str(dest[n]).lower() == str(v).lower:
            # should have better controls for when the case matters
            if sdnsh.description:
                print 'ADD %s skipping updating %s <-> %s' % (n, dest[n], v)
        else:
            dest[n] = v


def command_query_table(obj_type, data,
                        clear = True,
                        key = None, append = None, scoped = None, sort = None, crack = None):
    """
    Leave the result in command's global query_result, which can
    be used by other c_action steps

    'key' is one or more fields which are concatenated together to form
    the display-pipeline's version of a primary key.   It could be the
    actual primary key of the table, or it could be some fields which
    appear in all the rows.   Once the 'key' is constructed, it used to
    determine how results are added to the command.query_result.

    If the existing entries are to be 'cleared', then te primary key's
    are simply added to the table.  When the entries aren't cleared, then
    the computed primary key is used to join against existing items.

    Finally, the dict field name for the primary key is a single character: '@'
    This name was picked since its not possible for the database to ever
    use that name.
    """

    if not mi.obj_type_exists(obj_type):
        raise error.CommandDescriptionError("Unknown obj-type: %s" % obj_type)
        
    if sdnsh.description:   # description debugging
        print "command_query_table:", obj_type, data, clear, key, append, scoped, sort, crack

    if 'scoped' in data:
        scoped=data['scoped']
        del data['scoped']

    result = command_query_object(obj_type, data, scoped, sort)
    if sdnsh.description:   # description debugging
        print "command_query_table: %d entries found, using %s" % \
                (len(result), data)

    if crack:
        if crack == True:
            crack = mi.pk(obj_type)
        for entry in result:
            mi.split_compound_into_dict(obj_type, crack, entry, True)

    if append:
        for entry in result:
            if type(append) == dict:
                entry.update(append)
            elif type(append) == list:
                entry.update(dict(append))
            else:
                entry[append] = True

    # all the field from all the rows need to be present.
    if key:
        fields = key.split('|')

    if clear:
        command.query_result = result
        if key:
            for r in result:
                missing =  missing_part(fields, r)
                if missing:
                    if sdnsh.description:
                        print "command_query_table: ' \
                              ' missing field in row %s (%s) " % (missing, obj_type)
                    continue
                r['@'] = '|'.join([obj_type_field_case(r, obj_type, f) for f in fields])
    else:
        if key == None:
            if command.query_resuls != None:
                command.query_result += result
            else:
                command.query_result = result
        else:
            r_dict = {}
            for r in result:
                missing =  missing_part(fields, r)
                if missing:
                    if sdnsh.description:
                        print "command_query_table: ' \
                              ' missing field in row %s (%s) " % (missing, obj_type)
                    continue
                pk = '|'.join([r[f] for f in fields])
                r_dict[pk] = r
            if hasattr(command, 'query_result') and command.query_result:               
                for qr in command.query_result:
                    if '@' in qr and qr['@'] in r_dict:
                        add_fields(qr, r_dict[qr['@']])
                        del r_dict[qr['@']]
                command.query_result += r_dict.values()
            else:
                for (r, value) in r_dict.items():
                    value['@'] = '|'.join([value[f] for f in fields])
                command.query_result = r_dict.values()


def command_query_rest(data,
                       url = None, path = None, clear = True,
                       key = None, rest_type = None, scoped = None, sort = None, append = None):
    """
    Leave the result in command's global query_result, which can
    be used by other c_action steps (query-table, join-table, join-rest, display)

    'key' is one or more fields which are concatenated together to form
    the display-pipeline's version of a primary key.   It could be the
    actual primary key of the table, or it could be some fields which
    appear in all the rows.   Once the 'key' is constructed, it used to
    determine how results are added to the command.query_result.

    If the existing entries are to be 'cleared', then te primary key's
    are simply added to the table.  When the entries aren't cleared, then
    the computed primary key is used to join against existing items.

    Finally, the dict field name for the primary key is a single character: '@'
    This name was picked since its not possible for the database to ever
    use that name.

    """

    if sdnsh.description:   # description debugging
        print "command_query_rest:", url, path, rest_type, data, scoped, sort, append

    if url == None and path == None:
        raise error.CommandDescriptionError("missing url or path")
        
    if path:
        schema = sdnsh.sdndb.schema_detail(path)
        if schema:
            result = sdnsh.sdndb.data_rest_request(path)
        if key:
            # create a key dictionary, with the key values, pointing to
            # a psth in the schema.
            pass
        print 'PATH', path, result
    else:
        # if url is a list, pick the first one which can be build from the data
        if type(url) == list:
            select_url = url
        else:
            select_url = [url]

        use_url = None
        for u in select_url:
            try:
                use_url = (u % data)
                break
            except:
                pass

        if use_url == None:
            if sdnsh.description:   # description debugging
                print "command_query_rest: no url found"
            return

        query_url = "http://%s/rest/v1/" % sdnsh.controller + use_url

        if sdnsh.description:   # description debugging
            print "command_query_rest: query ", query_url
        try:
            result = sdnsh.store.rest_simple_request(query_url)
            check_rest_result(result)
            entries = json.loads(result)
        except Exception, e:
            if sdnsh.description or sdnsh.debug:
                print 'command_query_rest: ERROR url %s %s' % (url, e)
            entries = []

        if entries == None or len(entries) == 0:
            if sdnsh.description:   # description debugging
                print "command_query_rest: no new entries ", query_url
            if clear:
                command.query_result = None
            return

        # It certainly seems possible to map from url's to the type associated,
        # with the result, but it also makes sense to encode that type information
        # into the description
        if rest_type:
            result = command_display_rest_type_converter(None,
                                                         rest_type,
                                                         data,
                                                         entries)
            if sdnsh.description:   # description debugging
                print "command_query_rest: %s #entries %d " % (url, len(entries))
                print result
        else:
            result = []
            if (onos == 1) and (url == 'links'):
                for entry in entries:
                    src = entry.get('src')
                    dst = entry.get('dst')
                    for tempEntry in entries:
                        if cmp(src, tempEntry.get('dst')) == 0:
                            if cmp(dst, tempEntry.get('src')) == 0:
                                entries.remove(tempEntry)
                    result.append({
                       'src-switch'          : entry['src']['dpid'],
                       'src-port'            : entry['src']['portNumber'],
                       'src-port-state'      : 0,
                       'dst-switch'          : entry['dst']['dpid'],
                       'dst-port'            : entry['dst']['portNumber'],
                       'dst-port-state'      : 0,
                       'type'                : entry['type'],
                    })
            else:
                result = entries
        
    if append:
        for entry in result:
            if type(append) == dict:
                entry.update(append)
            elif type(append) == list:
                entry.update(dict(append))
            else:
                entry[append] = True
    
    if key:
        fields = key.split('|')

    if clear:
        command.query_result = result
        if key:
            for r in result:
                r['@'] = '|'.join([r[f] for f in fields])
    else:
        if key == None:
            if command.query_result != None:
                command.query_result += result
            else:
                command.query_result = result
        else:
            r_dict = {}
            for r in result:
                missing =  missing_part(fields, r, key_case = True)
                if missing:
                    if sdnsh.description:
                        print "command_query_rest: missing field %s in row %s" % (missing, r)
                    continue
                pk = '|'.join([case_cvt(f, r) for f in fields])
                r_dict[pk] = r
            for qr in command.query_result:
                if '@' in qr and qr['@'] in r_dict:
                    add_fields(qr, r_dict[qr['@']])


def command_join_rest(url, data, key, join_field,
                      add_field = None, rest_type = None, crack = None, url_key = None):
    
    """
    url-key allows single row results to have a name:value added to the
    entry in situations where a single dictionary is computed after the
    rest-type conversion.   this allows simple results from the url to
    have a keyword added to allow joins.
    """
    if not hasattr(command, 'query_result'):
        if sdnsh.description:   # description debugging
            print "command_join_rest: no entries found"
        return
        
    if command.query_result == None:
        if sdnsh.description:   # description debugging
            print "command_join_rest: query_result: None"
        return

    if sdnsh.description:   # description debugging
        print "command_join_rest: %d entries found, using %s, url %s" % \
                (len(command.query_result), data, url)
        print "command_join_rest:", data, key, join_field

    if url == None:
        return
    if join_field == None:
        return
    if key == None:
        return


    # Collect all the queries, removing any duplicates
    queries = {}
    for entry in command.query_result:
        # if url is a list, pick the first one which can be build from the data
        if type(url) == list:
            select_url = url
        else:
            select_url = [url]

        use_url = None
        for u in select_url:
            try:
                use_url = (u % entry)
                break
            except:
                pass

        if use_url == None:
            if sdnsh.description:   # description debugging
                print "command_join_rest: no url found", url
            continue
        query_url = "http://%s/rest/v1/" % sdnsh.controller + use_url

        if sdnsh.description:   # description debugging
            print "command_join_rest: query ", query_url, entry
        if query_url in queries:
            continue
        
        try:
            result = sdnsh.store.rest_simple_request(query_url)
            check_rest_result(result)
            entries = json.loads(result)
        except Exception, e:
            entries = []

        if entries == None or len(entries) == 0:
            continue

        # It certainly seems possible to map from url's to the type associated,
        # with the result, but it also makes sense to encode that type information
        # into the description
        if rest_type:
            queries[query_url] = command_display_rest_type_converter(None,
                                                                     rest_type,
                                                                     data,
                                                                     entries)
            #
            # url_key allows the addition of a key for joining for single results
            if url_key and len(queries[query_url]) == 1:
                queries[query_url][0][url_key] = entry.get(url_key)
                
            if sdnsh.description:   # description debugging
                print "command_join_rest: %s #entries %d #result %s" % \
                        (url, len(entries), len(queries[query_url]))
        else:
            queries[query_url] = entries
            
    # From the query results, generate the dictionary to join through

    key_parts = key.split('|')      # all the fields needed to make a key
    key_dict = {}                   # resulting key dictionary
    for (url, value) in queries.items():
        for entry in value:
            # see if all the key parts are in the entry
            missing =  missing_part(key_parts, entry)
            if missing:
                if sdnsh.description:
                    print 'command_join_rest: missing field %s in %s' % (missing, entry)
                continue
            new_key = '|'.join([str(entry[kn]) for kn in key_parts])
            if sdnsh.description:   # description debugging
                print 'command_join_rest: new-key', new_key
            key_dict[new_key] = entry

    # Using the key-dictinoary, look for matches from the original entries

    if add_field:
        parts = add_field.split('|')
        from_fields = None
        if len(parts):
            add_field = parts[0]
            from_fields = parts[1:]

    join_parts = join_field.split('|')
    for entry in command.query_result:
        if len(join_parts):
            missing = missing_part(join_parts, entry, key_case = True)
            if missing:
                if sdnsh.description:   # description debugging
                    print "command_join_rest: missing field %s in %s" % (missing, entry)
                continue
                
            joiner = '|'.join([case_cvt(kn, entry) for kn in join_parts])
        else:
            if sdnsh.description:   # description debugging
                print "command_join_rest: joining ",  entry, join_field, entry.get(join_field)
            if not join_field in entry:
                continue
            joiner = case_cvt(join_field, entry)

        if sdnsh.description:   # description debugging
            print "command_join_rest: joining ",  entry, joiner, key_dict.get(joiner)

        if joiner in key_dict:
            # add all the entries from the key_dict 
            if sdnsh.description:   # description debugging
                print 'command_join_rest: ADD', key_dict[joiner]
            if add_field == None:
                add_fields(entry, key_dict[joiner])
            elif from_fields:
                if len(from_fields) == 1:
                    # add a single field
                    if from_fields[0] in key_dict[joiner]:
                        entry[add_field] = key_dict[joiner][from_fields[0]]
                else:
                    # add a dictionary
                    entry[add_field] = dict([[ff, key_dict[joiner][ff]]
                                              for ff in from_fields])
            else:
                entry[add_field] = key_dict[joiner]

    if sdnsh.description:   # description debugging
        print "command_join_rest: ", command.query_result


def command_join_table(obj_type, data, key, join_field,
                       key_value = None, add_field = None, crack = None):
    """
    Add fieds to the current command.query_result by looking up the entry in
    the db/store.   key represents the value of the index to use from
    the entries read from the database.  The key can be composed of
    multiple fields within the entry.   The join_field is the name
    of the field within the command.query_result to use as the value to match
    against the key field.

    When key_value is None, the matched entry from the join_field's is
    treated as a dictionary, and all the pair of name:values are added
    directly to the new entry.   

    When key_value is a field name, the joined entries are collected 
    as a list, and added to the new entry a the key_value name.
    (see the use of tag-mapping as an example)
    """
    if not hasattr(command, 'query_result'):
        if sdnsh.description:   # description debugging
            print "command_join_table: no entries found"
        return

    if command.query_result == None:
        if sdnsh.description:   # description debugging
            print "command_join_table: query_result: None"
        return
    
    if sdnsh.description:   # description debugging
        print "command_join_table: %d entries found, using %s, obj_type %s %s %s" % \
                (len(command.query_result), data, obj_type, key, join_field)
        print "command_join_table:", data, key, join_field

    if join_field == None:
        return
    if key == None:
        return

    if not mi.obj_type_exists(obj_type):
        raise error.CommandDescriptionError("Unknown obj-type: %s" % obj_type)

    # build the join_dict, which will have keys for the items to
    # add into the entries
    if not mi.obj_type_has_model(obj_type):
        entries = rest_to_model.get_model_from_url(obj_type, data)
    else:
        entries = sdnsh.get_table_from_store(obj_type)

    # determine whether specific field names are added
    if add_field:
        parts = add_field.split('|')
        from_fields = None
        if len(parts):
            add_field = parts[0]
            from_fields = parts[1:]

    # constuct the join key for each row from the db table
    key_parts = key.split('|')      # all the fields needed to make a key
    key_dict = {}                   # resulting key dictionary
    for entry in entries:
        # see if all the key parts are in the entry
        missing = missing_part(key_parts, entry)
        if missing:
            if sdnsh.description:   # description debugging
                print "command_join_table: missing field %s in %s" % (missing, entry)
            continue

        new_key = '|'.join([obj_type_field_case(entry, obj_type, kn) for kn in key_parts])
        if sdnsh.description:   # description debugging
            print 'command_join_table: new-key', new_key, key_value
        if key_value:
            if not new_key in key_dict:
                key_dict[new_key] = [entry]
            else:
                key_dict[new_key].append(entry)
        else:
            key_dict[new_key] = entry


    # let 'crack' contain the field's name, not a boolean.
    if crack and crack == True:
        crack = mi.pk(obj_type)

    # Using the key-dictinoary, look for matches from the original entries

    join_parts = join_field.split('|')
    for entry in command.query_result:
        if len(join_parts):
            missing =  missing_part(join_parts, entry, key_case = True)
            if missing:
                if sdnsh.description:   # description debugging
                    print "command_join_table: missing field %s in %s" % (missing, entry)
                continue
                
            joiner = '|'.join([case_cvt(kn, entry) for kn in join_parts])
        else:
            if sdnsh.description:   # description debugging
                print "command_join_table: joining ",  entry, join_field, entry.get(join_field)
            if not join_field in entry:
                continue
            joiner = case_cvt(join_field, entry)

        if joiner in key_dict:
            if crack:
                if not crack in key_dict[entry[joiner]]:
                    if sdnsh.description:   # description debugging
                        print "command_join_table: field %s not in entry" % crack, key_dict[joiner]
                else:
                    mi.split_compound_into_dict(obj_type, crack, key_dict[joiner], True)

            # add all the entries from the key_dict 
            if sdnsh.description:   # description debugging
                print 'command_join_table: ADD %s as %s ' % (key_dict[joiner], add_field)
            if add_field == None:
                if key_value:
                    entry[key_value] = key_dict[joiner]
                else:
                    add_fields(entry, key_dict[joiner])
            elif from_fields:
                if len(from_fields) == 1:
                    # add a single field
                    if type(key_dict[joiner]) == list:
                        entry[add_field] = [x[from_fields[0]] for x in key_dict[joiner]]
                    else:
                        entry[add_field] = key_dict[joiner][from_fields[0]]
                else:
                    # add a dictionary with named fields
                    if type(key_dict[joiner]) == list:
                        for item in key_dict[joiner]:
                            entry[add_field] = dict([[ff, item[ff]]
                                                      for ff in from_fields])
                    else:
                        entry[add_field] = dict([[ff, key_dict[joiner][ff]]
                                                  for ff in from_fields])
                    
            else:
                entry[add_field] = key_dict[joiner]

    if sdnsh.description:   # description debugging
        print "command_join_table: ", command.query_result


def command_display_rest(data, url = None, sort = None, rest_type = None,
                         table_format = None, title = None, detail = None):
    """
    Perform a call to the rest api, and format the result.

    When sort isn't None, it names a field whose's value are sorted on.
    """
    #just a hack check to implement decending sorting
    descending = False
    #raise error.ArgumentValidationError('\n\n\n %s' % (descending))
    if sdnsh.description:   # description debugging
        print "command_display_rest: ", data, url, rest_type, table_format, detail

    if not url:
        url = data.get('url')
    if not table_format:
        table_format = data.get('format')

    check_single_entry = True

    # if url is a list, pick the first one which can be build from the data
    select_url = url
    if url and type(url) == list:
        for u in url:
            try:
                select_url = (u % data)
                select_url = u # select this url from the list
                break
            except:
                pass

    if not detail:
        detail = data.get('detail', 'default')
    url = "http://%s/rest/v1/" % sdnsh.controller + (select_url % data)

    result = sdnsh.store.rest_simple_request(url)
    check_rest_result(result)
    if sdnsh.description:   # description debugging
        print "command_display_rest: result ", result
    entries = json.loads(result)
        #rest_type = None
        #raise error.ArgumentValidationError('\n\n\n %s' % (attributes))
    #if 'realtimestats' in data and data['realtimestats'] == 'group':

    entries2 = None


    if 'realtimestats' in data and data['realtimestats'] == 'group':
        url2 = "http://%s/rest/v1/" % sdnsh.controller + ("realtimestats/groupdesc/%(dpid)s/" % data)
        result2 = sdnsh.store.rest_simple_request(url2)
        check_rest_result(result2)
        if sdnsh.description:   # description debugging
            print "command_display_rest: groupdesc result ", result2
        entries2 = json.loads(result2)
        
    # It certainly seems possible to map from url's to the type associated,
    # with the result, but it also makes sense to encode that type information
    # into the description
    if 'routerrealtimestats' in data  and data['routerrealtimestats'] == 'adjacency':
        rest_type =False
    if rest_type:
        entries = command_display_rest_type_converter(table_format,
                                                      rest_type,
                                                      data,
                                                      entries)
        if 'realtimestats' in data and data['realtimestats'] == 'group':
            if entries2 is not None:
                entries2 = command_display_rest_type_converter(table_format,
                                                      rest_type,
                                                      data,
                                                      entries2)

    if 'router' in data  and data['router'] == 'router':
        combResult = []
        for entry in entries:
            attributes = entry.get('stringAttributes')
            #raise error.ArgumentValidationError('\n\n\n %s' % (attributes))
            combResult.append({
                       'dpid'           : entry.get('dpid'),
                       'routerIP'       : attributes['routerIp'],
                       'name'           : attributes['name'],
                       'isEdgeRouter'   : attributes['isEdgeRouter'],
                       'routerMac'      : attributes['routerMac'],
                       'nodeSId'        : attributes['nodeSid'],
                       },)
        entries = combResult
    #raise error.ArgumentValidationError('\n\n\n %s' % (entries))
    if 'routerrealtimestats' in data  and data['routerrealtimestats'] == 'port':
        #raise error.ArgumentValidationError('\n\n\n %s' % (data))
        combResult = []
        portList = entries
        for port in portList:
            portData = port.get("port")
            name = portData.get("stringAttributes").get('name')
            portNo = portData.get("portNumber") & 0xFFFF # converting to unsigned16int
            subnetIp = port.get("subnetIp")
            adjacency = str(port.get('adjacency'))
            combResult.append({
                               'name'            :name,
                               'portNo'           : portNo,
                               'subnetIp'         : subnetIp,
                               'adjacency'        : adjacency,
                               })
        entries = combResult
    if 'routerrealtimestats' in data  and data['routerrealtimestats'] == 'adjacency':
        #raise error.ArgumentValidationError('\n\n\n %s' % (entries))
        #raise error.ArgumentValidationError('\n\n\n %s' % (entries))
        combResult = []
        adjacencyPairList = entries
        for adjacencyPair in adjacencyPairList:
            adjacencySid = adjacencyPair.get("adjacencySid")
            ports = adjacencyPair.get("ports")
            combResult.append({
                               'adjacencySid'    : adjacencySid,
                               'ports'           : ports,
                               })
        entries = combResult
    #raise error.ArgumentValidationError('\n\n\n %s' % (data))

    if 'showtunnel' in data  and (data['showtunnel'] == 'tunnel' or data['detail'] == 'details'):
        #eraise error.ArgumentValidationError('\n\n\n %s' % (entries))
        combResult = []
        tunnelList = entries
        for tunnel in tunnelList:
            labelStackList = (tunnel.get('labelStack'))
            labelStackString ='['
            for labelSack in labelStackList:
                for label in labelSack:
                    labelStackString += (label + ',')
            if labelStackString == '[':
                labelStackString = ''
            else:
                labelStackString = labelStackString[:-1]
                labelStackString += ']'
            tunnelId = tunnel.get('tunnelId')
            tunnelPath = tunnel.get('tunnelPath')
            dpidGroup = str(tunnel.get('dpidGroup'))
            dpidGroup= remove_unicodes(dpidGroup)
            policies = tunnel.get('policies')
            combResult.append({
                               'tunnelId'       : tunnelId,
                               'labelStack'     : labelStackString,
                               'dpidGroup'      : dpidGroup,
                               'tunnelPath'     : tunnelPath,
                               'policies'       : policies,
                               })
        entries = combResult

    if 'showpolicy' in data  and data['showpolicy'] == 'policy':
        #raise error.ArgumentValidationError('\n\n\n %s' % (data))
        combResult = []
        portList = entries
        for policy in portList:
            policyId = policy.get("policyId")
            policyType = policy.get("policyType")
            priority = policy.get("priority")
            tunnelId = policy.get('tunnelId')
            match = policy.get("match")
            dstIpAddress = match.get('dstIpAddress')['value'] if match.get('dstIpAddress') else '*'
            dstMacAddress = match.get('dstMacAddress')['value'] if match.get('dstMacAddress') else '*'
            dstTcpPortNumber = match.get('dstTcpPortNumber') if match.get('dstTcpPortNumber') else '*'
            etherType = ('0x'+ str(match.get('etherType'))) if match.get('etherType') else '*'
            ipProtocolNumber = match.get('ipProtocolNumber') if match.get('ipProtocolNumber') else '*'
            srcIpAddress = match.get('srcIpAddress')['value'] if match.get('srcIpAddress') else '*'
            srcMacAddress = match.get('srcMacAddress')['value'] if match.get('srcMacAddress') else '*'
            srcTcpPortNumber = match.get('srcTcpPortNumber') if match.get('srcTcpPortNumber') else '*'
            combResult.append({
                               'policyId'        : policyId,
                               'policyType'      : policyType,
                               'tunnelId'        : tunnelId,
                               'priority'        : priority,
                               'dstIpAddress'    : dstIpAddress,
                               'dstMacAddress'   : dstMacAddress,
                               'dstTcpPortNumber': dstTcpPortNumber,
                               'etherType'       : etherType,
                               'ipProtocolNumber': ipProtocolNumber,
                               'srcIpAddress'    : srcIpAddress,
                               'srcMacAddress'   : srcMacAddress,
                               'srcTcpPortNumber': srcTcpPortNumber,
                               
                               })
        entries = combResult

    if 'realtimestats' in data and 'tabletype' in data and data['realtimestats'] == 'table':
        combResult = []
        if data['tabletype'] == 'ip':
            #for decending sorting
            descending = True
            for ipTableEntry in entries:
                match = ipTableEntry['match']
                networkDestination = '*'
                if match :
                    networkDestination = match.get('networkDestination') if match.get('networkDestination') else '*'
                    #raise error.ArgumentValidationError('\n\n\n %s' % json.tool(entries))
                instructions = ipTableEntry['instructions']
                actions = str(instructions[0]) if instructions[0] else None
                if actions != None:
                    actions = remove_unicodes(actions)
                    actions = renameActions(actions)
                    actions = actions.lower()
                else:
                    actions =''
                combResult.append({
                       'switch'        : ipTableEntry['switch'],
                       'byteCount'     : ipTableEntry['byteCount'],
                       'packetCount'   : ipTableEntry['packetCount'],
                       'priority'      : ipTableEntry['priority'],
                       'cookie'        : ipTableEntry['cookie'],
                       'durationSeconds'         : ipTableEntry['durationSec'],
                       'networkDestination'      : networkDestination,
                       'actions'                 : actions,
                    })
        elif data['tabletype'] == 'mpls':
            for ipTableEntry in entries:
                match = ipTableEntry['match']
                mplsTc =  '*'
                mplsLabel = '*'
                mplsBos = '*'
                if match :
                    mplsTc = match.get('mplsTc') if match.get('mplsTc') else '*'
                    mplsLabel = match.get('mplsLabel') if match.get('mplsLabel') else '*'
                    mplsBos = match.get('mplsBos') if match.get('mplsBos') else '*'
                instructions = ipTableEntry['instructions']
                #raise error.ArgumentValidationError('\n\n\n %s' %len(actions))
                actions = str(instructions[0])if instructions[0] else None
                if actions != None:
                    actions = remove_unicodes(actions)
                    actions = renameActions(actions)
                    actions = actions.lower()
                else:
                    actions =''
                combResult.append({
                       'switch'        : ipTableEntry['switch'],
                       'byteCount'     : ipTableEntry['byteCount'],
                       'packetCount'   : ipTableEntry['packetCount'],
                       'cookie'        : ipTableEntry['cookie'],
                       'priority'      : ipTableEntry['priority'],
                       'mplsTc'         : mplsTc,
                       'mplsLabel'      : mplsLabel,
                       'mplsBos'        : mplsBos,
                       'durationSeconds'        : ipTableEntry['durationSec'],
                       'actions'        : actions
                    })
        elif data['tabletype'] == 'acl':
            descending = True
            for ipTableEntry in entries:
                match = ipTableEntry['match']
                networkDestination ='*'
                networkProtocol = '*'
                networkSource = '*'
                mplsTc = '*'
                mplsLabel = '*'
                mplsBos = '*'
                transportDestination = '*'
                inputPort = '*'
                transportSource = '*'
                dataLayerSource = '*'
                dataLayerDestination = '*'
                dataLayerType = '*'
                if match :
                    networkDestination = match.get('networkDestination') if match.get('networkDestination') else '*'
                    networkProtocol = match.get('networkProtocol') if match.get('networkProtocol') else '*'
                    networkSource = match.get('networkSource') if match.get('networkSource') else '*'
                    mplsTc = match.get('mplsTc') if match.get('mplsTc') else '*'
                    mplsLabel = match.get('mplsLabel')if match.get('mplsLabel') else '*'
                    transportDestination = match.get('transportDestination') if match.get('transportDestination') else '*'
                    transportSource = match.get('transportSource') if match.get('transportSource') else '*'
                    inputPort = match.get('inputPort') if match.get('inputPort') else '*'
                    dataLayerSource = match.get('dataLayerSource') if match.get('dataLayerSource') else '*'
                    dataLayerDestination = match.get('dataLayerDestination') if match.get('dataLayerDestination') else '*'
                    dataLayerType= match.get('dataLayerType') if match.get('dataLayerType') else '*'
                    mplsBos = match.get('mplsBos') if match.get('mplsBos') else '*'
                instructions = ipTableEntry['instructions']
                actions = str(instructions[0])if instructions[0] else None
                if actions != None:
                    actions = remove_unicodes(actions)
                    actions = renameActions(actions)
                    actions = actions.lower()
                else:
                    actions = ''
                combResult.append({
                       'switch'        : ipTableEntry['switch'],
                       'byteCount'     : ipTableEntry['byteCount'],
                       'packetCount'   : ipTableEntry['packetCount'],
                       'cookie'        : ipTableEntry['cookie'],
                       'priority'      : ipTableEntry['priority'],
                       'inputPort'               : inputPort,
                       'durationSeconds'         : ipTableEntry['durationSec'],
                       'networkSource'           : networkSource,
                       'networkDestination'      : networkDestination,
                       'networkProtocol'         : networkProtocol,
                       'dataLayerType'           : dataLayerType,
                       'dataLayerSource'         : dataLayerSource,
                       'dataLayerDestination'    : dataLayerDestination,
                       'mplsTc'                  : mplsTc,
                       'mplsLabel'               : mplsLabel,
                       'mplsBos'                 : mplsBos,
                       'transportDestination'    : transportDestination,
                       'transportSource'         : transportSource,
                       'actions'                 : actions
                    })
        entries = combResult

    if 'realtimestats' in data and data['realtimestats'] == 'group':
        combResult = []
        for groupStatEntry in entries:
            groupId = groupStatEntry["groupId"]
            groupDescEntry = None
            for entry in entries2:
                if groupId == entry["groupId"]:
                    groupDescEntry = entry
                    break
            if groupDescEntry is '':
                print "command_display_rest: missing group desc for group id %s" % (groupId)
                continue
            for bucketId in range(len(groupStatEntry['bucketStats'])):
                setsrcmac = ''
                if 'SET_DL_SRC' in groupDescEntry['bucketsActions'][bucketId]:
                    setsrcmac = groupDescEntry['bucketsActions'][bucketId]['SET_DL_SRC']
                setdstmac = ''
                if 'SET_DL_DST' in groupDescEntry['bucketsActions'][bucketId]:
                    setdstmac = groupDescEntry['bucketsActions'][bucketId]['SET_DL_DST']
                pushmpls = ''
                if 'PUSH_MPLS_LABEL' in groupDescEntry['bucketsActions'][bucketId]:
                    pushmpls = groupDescEntry['bucketsActions'][bucketId]['PUSH_MPLS_LABEL']
                popmpls = ''
                if 'POP_MPLS' in groupDescEntry['bucketsActions'][bucketId]:
                    popmpls = groupDescEntry['bucketsActions'][bucketId]['POP_MPLS']
                outport = ''
                if 'OUTPUT' in groupDescEntry['bucketsActions'][bucketId]:
                    outport = groupDescEntry['bucketsActions'][bucketId]['OUTPUT']
                goToGroup = ''
                if 'goToGroup' in groupDescEntry['bucketsActions'][bucketId]:
                    goToGroup = groupDescEntry['bucketsActions'][bucketId]['goToGroup']
                setBos= ''
                if 'PUSH_MPLS_BOS' in groupDescEntry['bucketsActions'][bucketId]:
                    setBos = groupDescEntry['bucketsActions'][bucketId]['PUSH_MPLS_BOS']
                COPY_TTL_IN= ''
                if 'COPY_TTL_IN' in groupDescEntry['bucketsActions'][bucketId]:
                    COPY_TTL_IN = groupDescEntry['bucketsActions'][bucketId]['COPY_TTL_IN']
                COPY_TTL_OUT= ''
                if 'COPY_TTL_OUT' in groupDescEntry['bucketsActions'][bucketId]:
                    COPY_TTL_OUT = groupDescEntry['bucketsActions'][bucketId]['COPY_TTL_OUT']
                DEC_MPLS_TTL= ''
                if 'DEC_MPLS_TTL' in groupDescEntry['bucketsActions'][bucketId]:
                    DEC_MPLS_TTL = groupDescEntry['bucketsActions'][bucketId]['DEC_MPLS_TTL']
                DEC_NW_TTL= ''
                if 'DEC_NW_TTL' in groupDescEntry['bucketsActions'][bucketId]:
                    DEC_NW_TTL = groupDescEntry['bucketsActions'][bucketId]['DEC_NW_TTL']

                combResult.append({
                       'groupid'       : groupId,
                       'grouptype'     : groupDescEntry['groupType'],
                       'totalpktcnt'   : groupStatEntry['packetCount'],
                       'totalbytecnt'  : groupStatEntry['byteCount'],
                       'bucketpktcnt'  : groupStatEntry['bucketStats'][bucketId]['pktCount'],
                       'bucketbytecnt' : groupStatEntry['bucketStats'][bucketId]['byteCount'],
                       'setsrcmac'     : setsrcmac,
                       'setdstmac'     : setdstmac,
                       'pushMplsLabel' : pushmpls,
                       'popmpls'       : popmpls,
                       'outport'       : outport,
                       'goToGroup'     : goToGroup,
                       'setBos'        : setBos,
                       'COPY_TTL_IN'   : COPY_TTL_IN,
                       'COPY_TTL_OUT'  : COPY_TTL_OUT,
                       'DEC_MPLS_TTL'  : DEC_MPLS_TTL,
                       'DEC_NW_TTL'    : DEC_NW_TTL,
                    })
        entries = combResult
    #
    if format:
        #
        detail = command_display_rest_join_entries(table_format, data, entries, detail)
        #if 'realtimestats' in data and data['realtimestats'] == 'flow':
        #    entries = sdnsh.fix_realtime_flows(entries)
        #    check_single_entry = False

        if 'realtimestats' in data and data['realtimestats'] == 'features':
            for entry in entries:
                entry['stp-state'] = entry['state']

        # update any of the pretty-printer tables based on the table_format (obj_type)
        obj_type_show_alias_update(table_format % data)

        if check_single_entry and entries and len(entries) == 1 and detail == 'details':
            return sdnsh.pp.format_entry(entries[0],
                                        table_format % data,
                                        detail,
                                        sdnsh.debug)
        if sort:
            if descending:
                reverse = True
            else:
                reverse = False
            def sort_cmp(x,y):
                for f in sort:
                    if f in x:
                        c = cmp(x.get(f), y.get(f)) 
                        if c != 0:
                            return c
                return 0
            entries = sorted(entries,  cmp=sort_cmp, reverse=reverse )

        display = sdnsh.pp.format_table(entries, table_format % data, detail)
    else:
        display = entries

    if title:
        return title + display
    return display


def command_crack(field):
    """
    Part of the show pipeline, split is typically used with rest api's
    not associated with the model (database), since the cli has enough
    details of the relationships between model fields to understand 
    which of the fields has a compound key value, and has options to
    crack those into component parts.

    The operation is called 'crack' (not split), since the other
    options for some of the actions is called 'crack'

    The field identifies the name of the field in the entry to
    split into parts, and the remaining '|' separated fields list
    the labels to associate in the result from each of the 
    split components.   Currently, the 'crack' character is '|',
    although this could be parameterized.
    """
    if sdnsh.description:   # description debugging
        print "command_split: ", field

    if hasattr(command, 'query_result'):
        entries = command.query_result
        if command.query_result == None:
            entries = []
    else:
        if sdnsh.description:   # description debugging
            print "command_join_table: no entries found"
        entries = []
    
    parts = field.split('|')
    if len(parts) == 0:
        if sdnsh.description:   # description debugging
            print "command_join_table: field doesn't contain labels" \
                   " use field|label1|label2|..."
        return

    field = parts[0]
    label = parts[1:]
    many = len(label)

    for entry in entries:
        if field in entry:
            parts = entry[field].split('|')
            if len(parts) and many >= len(parts) :
                # use enumerate to create a tuple for each item in parts,
                # assocaiting an index, which can be used to identify the
                # label to use for each of the elements; from that create
                # a dictionay, which is then used to update the entry
                entry.update(dict([[label[n],p] for (n,p) in enumerate(parts)]))


def command_display(data, table_format, detail = 'default', sort = None, title = None):
    
    if sdnsh.description:   # description debugging
        print "command_display: ", data, table_format, detail

    if 'detail' in data:
        detail = data['detail']

    if hasattr(command, 'query_result'):
        entries = command.query_result
        if command.query_result == None:
            entries = []
    else:
        if sdnsh.description:   # description debugging
            print "command_join_table: no entries found"
        entries = []
    
    if sdnsh.description:   # description debugging
        print "command_display: #entries ", len(entries)

    # XXX controller-node has an odd url, join-rest needs to be able to
    # be handed a complete url, and replace the ip address with the controller's
    # ip address.
    detail = command_display_table_join_entries(table_format, data, entries, detail)

    # update any of the pretty-printer tables based on the table_format (obj_type)
    obj_type_show_alias_update(table_format)

    # with_key manages whether a 'detail' or table is displayed.
    with_key = '<with_key>' if detail == 'details' and len(entries) > 0 else '<no_key>'

    # 
    if sort:
        def sort_cmp(x,y):
            for f in sort:
                if f in x:
                    c = utif.trailing_integer_cmp(x.get(f),y.get(f))
                    if c:
                        return c
            return 0
        entries = sorted(entries, cmp=sort_cmp)

    # use display_obj_type_rows since it (currently) joins fields for obj_types.
    display = sdnsh.display_obj_type_rows(table_format, entries, with_key, detail)

    if title:
        return title + display
    return display


def command_legacy_cli(obj_type, data, detail = 'default', scoped = None, sort = None):
    """
    Unfortunatly, the command descriptions don't have enough different
    detail to describe how to join specific distinct fields.  In the future,
    there will be rest api's for each of the cli requests; that should cause
    this trampoline code to become obsolete.
    """

    if sdnsh.description:   # description debugging
        print "command_legacy_cli: ", obj_type, data, detail, scoped, sort

    # update any of the pretty-printer tables based on the obj_type
    obj_type_show_alias_update(obj_type)

    #
    #
    # Various show command 'join' data to create a table not
    # directly available in the REST API, someday in the future,
    # these joins will be directly implemented in the REST API,
    # but these special cases still exist:
    #
    if 'running-config' in data:
        result = sdnsh.error_msg("No running-config choice")
        words = []
        if 'word' in data and data['word'] != 'all':
            words = [data['word']]

        if data['running-config'] == 'running-config':
            # 'show vns XXX running-config'
            if 'vnsname' in data and data['vnsname'] != 'all':
                return sdnsh.show_vns_running_config(data['vnsname'],data['tenant'])
            elif 'vns' in data and data['vns']=='all':
                data['running-config'] = 'vns'
            elif 'tenant' in data:
                data['running-config']='tenant'
                words=[data['tenant']]
        if data['running-config'] in run_config.registry_items_enabled():
            result = run_config.perform_running_config(data['running-config'], sdnsh, config, words)

        if result:
            return result
        return ''.join(config)

    if obj_type == 'running-config':
        return run_config.implement_show_running_config([])
            
    if obj_type == 'vns-interface':
        if scoped:
            # should check for missing 'id' in data
            data['vns'] = sdnsh.get_current_mode_obj()

        if 'vns' in data:
            if data['vns'] == 'all':
                return sdnsh.display_vns_interface(None, {}, '<no_key>')
            vns_name=data['vns']
            return sdnsh.display_vns_interface(vns_name, {'vns': vns_name },
                                           '<no_key>', detail = 'scoped')
        
    if obj_type == 'vns-switch-ports':
        if 'vns' in data:
            return sdnsh.show_vns_switch_ports([data['vns']])
        return sdnsh.show_vns_switch_ports([])

    if obj_type == 'switch-ports-vns':
        if 'dpid' in data:
            return sdnsh.show_switch_ports_vns([data['dpid']])
        return sdnsh.show_switch_ports_vns([])

    if obj_type == 'switch-interfaces':
        key = mi.pk(obj_type)
        if scoped:
            data['dpid'] = sdnsh.get_current_mode_obj()

        # in legacy_cli to join the switch-interfaces with port stats
        port_obj = 'port'
        entries = sdnsh.show_sort_obj_type(obj_type, 
                            command_query_object(port_obj, data, scoped, sort))

        # switch-interfaces is really class Port, and the primary key
        # is '#|switch|number, not name.

        entries_dict = dict([['%s|%s' % (x['switch'], x['name']), x] for x in entries])
        # collect switch-interface-config
        sic = 'switch-interface-config'
        if 'dpid' in data and data['dpid'] != 'all':
            sic_dict = create_obj_type_dict(sic, mi.pk(sic), mi.pk(sic), data['dpid'])
        else:
            sic_dict = create_obj_type_dict(sic, mi.pk(sic))

        # add switch-interface-config names when missing
        for (sic_id, sic_value) in sic_dict.items():
            if not sic_id in entries_dict:
                # add 'state' to this item for prettyprinting column width computation
                for sv in sic_value:
                    sv['state'] = ''
                entries += sic_value
                                                  
        # collect the stats for the interfaces
        stats_url = 'realtimestats/port/%(dpid)s/' % data
        url = "http://%s/rest/v1/" % sdnsh.controller + stats_url
        try:
            result = sdnsh.store.rest_simple_request(url)
            check_rest_result(result)
            stats = json.loads(result)

        except Exception, e:
            stats = {}

        # join realtimestats
        for entry in entries:
            if 'state' in entry:
                entry['stp-state'] = entry['state']
            stats_list = stats.get(entry['switch'])
            # Note, 'number' may be missing from entry if the switch
            # matches for switch-interface-config but the interface name
            # doesn't show up.
            if stats_list and 'number' in entry:
                ifn = entry['number']
                # Notice that the realtime stat's use a int for the 2^16 value here
                # The & 0xffff converts the "-x" to a positive 2^16 value
                item = [x for x in stats_list if (x['portNumber'] & 0xffff) == ifn]
                if len(item) == 1:
                    entry.update(item[0])
            if entry['id'] in sic_dict:
                entry.update(sic_dict[entry['id']][0])

        # Update the alias mappings for display
        obj_type_show_alias_update(obj_type)

        return sdnsh.pp.format_table(entries, obj_type, detail)

    if obj_type == 'tunnel-interfaces':
        # Use the active tunnels to identify the interfaces on the
        # switches which are the tunneling interfaces, with that
        # collect to port -> if_name mappings from 'port', then
        # find all the switches interfaces, convert those port numbers to
        # if names, to collect only tunneling interfaces.  Now collect
        # realtimestats for the switch's ports, and associate those
        # stats with any filtered interfaces, finally display the result
        tunnel_url = "tunnel-manager/%(dpid)s" % data
        url = "http://%s/rest/v1/" % sdnsh.controller + tunnel_url
        result = sdnsh.store.rest_simple_request(url)
        check_rest_result(result)
        tunnels = json.loads(result)

        # use the active tunnels to
        # collect dpid's, convert the remote ip's to interface names.
        tunnel_ports = {}
        for t in tunnels:
            quad = t['tunnelPorts'].split('.')
            if_name = "vta%03d%03d%03d%03d" % (int(quad[0]), int(quad[1]),
                                               int(quad[2]), int(quad[3]))
            key = "%s|%s" % (t['dpid'], if_name)
            if not key in tunnel_ports:
                tunnel_ports[key] = {t['dpid']: t['tunnelPorts']}

        # Collect interfaces on associated switch
        port_obj = 'port'
        entries = sdnsh.show_sort_obj_type(port_obj,
                            command_query_object(port_obj, data, scoped, sort))
        # Associate port names with interface names
        port_to_if_name = {}

        try:
            ports = sdnsh.get_table_from_store("port")
        except Exception, e:
            port = []

        for port in ports:
            key_string = '%s|%s' % (port['switch'], port['number'])
            port_to_if_name[key_string] = port['name']

        # Filter elements, 'filtered' only contains active tunnel interfaces
        filtered = []
        for e in entries:
            e['ifname'] = port_to_if_name[e['id']]
            key = '%s|%s' % (e['switch'], e['ifname'])
            if sdnsh.description:   # description debugging
                print command._line(), key
            if key in tunnel_ports:
                if sdnsh.description:   # description debugging
                    print command._line(), "Found ", e['id']
                filtered.append(e)
        entries = filtered

        # collect switch-interface-config
        sic = 'switch-interface-config'
        if 'dpid' in data:
            sic_dict = create_obj_type_dict(sic, mi.pk(sic), mi.pk(sic), data['dpid'])
        else:
            sic_dict = create_obj_type_dict(sic, mi.pk(sic))
                                                  
        # collect the stats for the interfaces
        stats_url = 'realtimestats/port/%(dpid)s/' % data
        url = "http://%s/rest/v1/" % sdnsh.controller + stats_url
        try:
            result = sdnsh.store.rest_simple_request(url)
            check_rest_result(result)
            stats = json.loads(result)
        except Exception, e:
            stats = {}

        # join realtimestats
        for entry in entries:
            if 'state' in entry:
                entry['stp-state'] = entry['state']
            stats_list = stats.get(entry['switch'])
            if stats_list and 'number' in entry:
                ifn = entry['number']
                # Notice that the realtime stat's use a int for the 2^16 value here
                # The & 0xffff converts the "-x" to a positive 2^16 value
                item = [x for x in stats_list if (x['portNumber'] & 0xffff) == ifn]
                if len(item) == 1:
                    entry.update(item[0])
            if entry['id'] in sic_dict:
                entry.update(sic_dict[entry['id']][0])

        obj_type_show_alias_update('switch-interfaces')

        return sdnsh.pp.format_table(entries, 'switch-interfaces', detail)
        
    if obj_type == 'host-vns-interface-vns':
        words = []
        for w in []: # list of options to display_vns_mac_address_table
            if w in data:
                words[w] = data[w]

        return sdnsh.display_vns_mac_address_table(data['vns'], words)

    if obj_type == 'config':
        if 'config' in data:
            if 'version' in data:
                return sdnsh.implement_show_config([data['config'],data['version']])
            return sdnsh.implement_show_config([data['config']])

        if 'config-diff' in data:
            if 'version' in data:
                return sdnsh.implement_show_config([ data['first'],
                                                     'diff',
                                                      data['second'],
                                                      data['version']])
            return sdnsh.implement_show_config([data['first'],
                                                'diff',
                                                data['second'], ])
        return sdnsh.implement_show_config([])

    if obj_type == 'vns-flow':
        if 'detail' in data:
            return sdnsh.show_vns_flow_annotated([data['vns'],
                                                  'flow',
                                                  data['detail']])
        return sdnsh.show_vns_flow_annotated([data['vns'], 'flow'])

    if obj_type == 'tech-support':
        return sdnsh.do_show_tech_support([])

    if obj_type == 'config-file':
        if 'file' in data:
            return sdnsh.implement_show_config_file(['config-file', data['config']])
        return sdnsh.implement_show_config_file(['config-file', ])

    if obj_type == 'logging':
        if 'log-name' in data:
            return sdnsh.implement_show_logging([data['log-name']])
        return sdnsh.implement_show_logging([])

    if obj_type == 'event-history':
        if 'count' in data:
            return sdnsh.do_show_event_history([data['event'],
                                                'last',
                                                str(data['count'])])
        return sdnsh.do_show_event_history([data['event']])

    if obj_type == 'flow-cache':
        words = []
        if 'counters' in data:
            words.append('counters')
        elif 'application' in data:
            words.append('app')
            words.append(data['application'])
            words.append('app-instance')
            words.append(data['instance'])

        return sdnsh.do_show_flow_cache(words)

    if obj_type in ['controller-stats', 'switch-stats']:
        #
        # data['id'] is the name of the controller
        helper_item = obj_type.replace('-stats','')
        if helper_item == 'controller':
            helper_item = 'controller-node'
        key = mi.pk(helper_item)
        words = [helper_item, data[key], 'stats']
        if 'stats-type' in data:
            words.append(data['stats-type'])
        for (n,v) in data.items():
            if not n in [key, 'stats', 'stats-type']:
                words.append(n)
                words.append(v)
        return sdnsh.helper_show_object_stats(words)

    if obj_type == 'switch-tcpdump':
        words = ['trace', data['dpid']]
        for (n,v) in data.items():
            if not n in ['tcpdump', 'dpid']:
                words.append(n)
        return sdnsh.do_trace(words)

    if obj_type == 'copy':
        words = [data['source']]
        if 'dest' in data:
            words.append(data['dest'])
        return sdnsh.implement_copy(words)

    if obj_type == 'write':
        return sdnsh.implement_write([data['target']])

    if obj_type == 'this':
        obj_type = sdnsh.get_current_mode_obj_type()
        show_this = mi.obj_type_show_this(obj_type)
        if not show_this:
            return sdnsh.do_show_object(['this'])
        result = []
        for show in show_this:
            if type(show) is list and len(show) >= 3:
                # [ object, format, detail ]
                if len(result) > 0:
                    result.append(mi.obj_type_show_title(show[0]))
                sort = None
                if len(show) > 3:
                    sort = show[3]
                result.append(command_display_table(show[0], {},
                                                    table_format = show[1],
                                                    detail = show[2],
                                                    sort = sort,
                                                    scoped = True))
            elif type(show) is list and len(show) == 2:
                # [ object, detail ]
                if len(result) > 0:
                    result.append(mi.obj_type_show_title(show[0]))
                result.append(command_display_table(show[0], {}, detail = show[1], scoped = True))
            else:
                result.append(sdnsh.do_show_object([show]))
        return '\n'.join(result)

    if obj_type == 'version':
        return sdnsh.do_show_version([])

    if obj_type == 'reload':
        return sdnsh.implement_reload()

    if obj_type == 'test-command':
        if data['test-type'] == 'packet-in':
            return sdnsh.implement_test_packet_in(data)
        if data['test-type'] == 'path':
            return sdnsh.implement_test_path(data)

    print 'command_legacy_cli: obj-type unknown: ', obj_type


def command_legacy_cli_no(obj_type, data, detail = 'default', scoped = None, sort = None):
    """
    Implement no command for trampoline code back to the original code
    """
    if obj_type == 'tag-mapping':
        return sdnsh.implement_no_tag(['tag', data['tag']])


def command_version(data):
    """
    The version command will later manage changing the syntax to match
    the requested version.
    """
    new_version = data.get('version')
    if new_version == None:
        return

    version = new_version # save for error message
    new_version = sdnsh.desc_version_to_path_elem(new_version)

    # skip version change is this is the current version.
    if sdnsh.desc_version == new_version:
        return

    # see if the requested version exists
    if not sdnsh.command_packages_exists(new_version):
        print 'No command description group for version %s' % version
        return

    # run 'env [envriron_vars] ... cli.py'
    command = ['env']
    command.append('CLI_COMMAND_VERSION=%s' % version)
    command.append('CLI_STARTING_MODE=config')
    if os.path.exists('/opt/sdnplatform/cli/bin/cli'):
        # controller VM
        command.append('/opt/sdnplatform/cli/bin/cli --init')
    else:
        # developer setup
        base = os.path.dirname(__file__)
        command.append(os.path.join(base, 'cli.py'))
        command.append('--init')

    # dump the command descriptions, and read a new set.
    # open a subshell with a new command version
    subprocess.call(command, cwd=os.environ.get("HOME"))

    return


def command_clearterm():
    """
    Print reset characters to the screen to clear the console
    """
    subprocess.call("reset")

def command_display_cli(data):
    """
    Display various cli details
    (this may need to be re-factored into some general "internal" state show
    """
    debug = []
    if sdnsh.debug:
        debug.append('debug')
    if sdnsh.debug_backtrace:
        debug.append('backtrace')

    modes = sdnsh.command_dict.keys() + sdnsh.command_nested_dict.keys()

    entry = {
               'version' : ', '.join(command.command_syntax_version.keys()),
               'desc'    : ', '.join(sorted(command.command_added_modules.keys())),
               'format'  : ', '.join(sorted(sdnsh.pp.format_added_modules.keys())),
               'modes'   : ', '.join(sorted(utif.unique_list_from_list(modes))),
               'debug'   : ', '.join(debug),
            }
    basic = sdnsh.pp.format_entry(entry, 'cli')

    mode_entries = command.command_submode_dictionary(modes)
    mode_table = sdnsh.pp.format_table(mode_entries, 'cli-modes')

    return basic + '\n\nCommand Submode Transition\n' + mode_table

    return


def delete_alias_by_id(alias_obj_type, alias_value):
    """
    Common delete operation for alias, based on primary key

    @param alias_obj_type string, name of table where single entry is removed
    @param alias_value string, value of primary key to delete
    """
    xref = mi.foreign_key_xref.get(alias_obj_type)
    if xref:
        # look for any referecnes to this alias_value.  Since this
        # is an alias table, only the pk ought to exist in the xref.
        # When the alias is getting removed, any references to it
        # via foreign keys must also get removed.
        if len(xref) > 1 or not mi.pk(alias_obj_type) in xref:
            print 'Internal Inconsistency'
        else:
            for (fk_obj_type, fk_field) in xref[mi.pk(alias_obj_type)]:
                rows = sdnsh.get_table_from_store(fk_obj_type,
                                                  fk_field,
                                                  alias_value,
                                                  'exact')
                for row in rows:
                    sdnsh.rest_delete_object(fk_obj_type, row[mi.pk(fk_obj_type)])
    sdnsh.rest_delete_object(alias_obj_type, alias_value)


def delete_alias_by_fk(alias_obj_type, foreign_key):
    """
    Common delete operation for alias, by foreign key

    @param alias_obj_type string, name of table where single entry is removed
    @param alias_value string, value of primary key to delete
    """
    # find all the id's based on the foreign key, then delete them all.
    # note: see similar midw alias_lookup_with_foreign_key()

    foreign_field = mi.alias_obj_type_field(alias_obj_type)
    try:
        rows = sdnsh.get_table_from_store(alias_obj_type,
                                          foreign_field,
                                          foreign_key,
                                          "exact")
    except Exception, e:
        raise error.CommandInternalError("Can't fetch %s:%s" %
                                           (foreign_field, foreign_key))
    pk = mi.pk(alias_obj_type)
    for row in rows:
        delete_alias_by_id(alias_obj_type, row[pk])


def command_delete_alias(obj_type, data):
    """
    Action for delete-alias

    A single row is deleted from an alias table.
    Current alias tables include host-alias, switch-alias, port-alias

    @param obj_type string, name of alias table to manage
    @param data dict, collection of field:value's from command description
    """
    if sdnsh.description:   # description debugging
        print "command_delete_alias: ", obj_type, data

    parent_id = sdnsh.get_current_mode_obj()

    key = mi.pk(obj_type)
    if key not in data:
        delete_alias_by_fk(obj_type, parent_id)
    else:
        delete_alias_by_id(obj_type, data[key])


def command_create_alias(obj_type, data, reserved = None, fail_if_exists = False):
    """
    Action for create-alias

    Current alias tables include host-alias, switch-alias, port-alias

    @param obj_type string, name of alias table to manage
    @param data dict, collection of field:value's from the command description
    """
    if sdnsh.description:   # description debugging
        print "command_create_alias: ", obj_type, data, reserved, fail_if_exists

    parent_obj_type = sdnsh.get_current_mode_obj_type()
    parent_id = sdnsh.get_current_mode_obj()

    key = mi.pk(obj_type)
    if key not in data:
        raise error.CommandInternalError("Alias table '%s': description "
                                           "doesn't populate correct '%s' field as data" %
                                           (obj_type, key))
    alias_value = data[key]
    #
    # Determine if the alias name is allowed.
    if alias_value in sdnsh.reserved_words:
        raise error.ArgumentValidationError('reserved name "%s" in "%s"'
                                              % (alias_value, ','.join(sdnsh.reserved_words)))
    if reserved and type(reserved) != list:
        reserved = [reserved]

    if reserved and alias_value in reserved:
        raise error.ArgumentValidationError('reserved name "%s" in "%s"'
                                              % (alias_value, ','.join(reserved)))

    # Walk the foreign key's in the (alias) obj-type, looking
    # for the parent reference.

    alias_fk = None
    obj_type_foreign_keys = mi.obj_type_foreign_keys(obj_type)
    if len(obj_type_foreign_keys) == 1:
        alias_fk = obj_type_foreign_keys[0]
    else:
        for alias_fn in obj_type_foreign_keys:
            (fk_ot, fk_fn) = mi.foreign_key_references(obj_type, alias_fn)
            if fk_ot == parent_obj_type:
                alias_fk = alias_fn

    if not alias_fk:
        raise error.CommandInternalError("Alias table '%s' has no foreign key to '%s'" %
                                           (obj_type, parent_obj_type))

    try:
        sdnsh.get_object_from_store(obj_type, alias_value)
        if sdnsh.description:   # description debugging
            print "command_create_alias: delete ", obj_type, alias_value
        if fail_if_exists:
            raise error.ArgumentValidationError("Interface name '%s' already in use - cannot reassign" %(alias_value))
        delete_alias_by_id(obj_type, alias_value)
    except:
        pass

    # Remove other existing alias for the same foreign key
    # (ie: only one alias per each item, this could be relaxed)
    # XXX improve method of managing errors here
    try:
        rows = sdnsh.get_table_from_store(obj_type,
                                          alias_fk,
                                          parent_id,
                                          "exact")
    except Exception, e:
        errors = sdnsh.rest_error_to_dict(e)
        print sdnsh.rest_error_dict_to_message(errors)
        rows = []

    for row in rows:
        try:
            delete_alias_by_id(obj_type, row[key])
            if row[alias_fk] != parent_id:
                sdnsh.warning("Removed additional alias '%s'"
                              ", also refers to %s '%s'" %
                              (row[key], parent_obj_type, parent_id))
        except:
            if sdnsh.debug or sdnsh.debug_backtrace:
                traceback.print_exc()

    # This set's the foreign key to allow the create to succeed
    c_dict = {
                key      : alias_value,
                alias_fk : parent_id,
             }

    if sdnsh.description:   # description debugging
        print "command_create_alias: create ", obj_type, c_dict
    result = sdnsh.rest_create_object(obj_type, c_dict)
    check_rest_result(result)
    result = sdnsh.rest_query_objects(obj_type, c_dict)
    check_rest_result(result)

    return None


def command_create_tag(obj_type, data):
    """
    obj_type needs to be one of the objects which implements
    a relationship to 'tag', for example:  tag-mac-mapping
    """

    item = sdnsh.get_current_mode_obj_type()
    fks = mi.obj_type_foreign_keys(obj_type)
    for fk in fks:
        (fk_obj, fk_name) = mi.foreign_key_references(obj_type, fk)
        if fk_obj == item:
            break
    else:
        raise error.CommandSemanticError( "type mapping %s doesn't have "
                        "relationship to the current object %s" %
                        (obj_type, item))

    if sdnsh.description:   # description debugging
        print "command_create_tag: create ", obj_type, data

    tag_and_value = data['tag'].split('=')
    if len(tag_and_value) != 2:
        # deal with tag_and_value's 'va=vb=vc...'
        raise error.CommandSemanticError("tag <[tag-namespace.]name>=<value> " 
                                         ": associate tag with host")

    tag_parts = tag_and_value[0].split('.')
    if len(tag_parts) == 0:
        raise error.CommandSemanticError("tag <[tag-namespace.]name>"
                                         ": must have a name")
    elif len(tag_parts) == 1:
        tag_namespace = "default"
        tag_name = tag_parts[0]
    elif len(tag_parts) >= 2:
        # the tag_name is not allowed to have '.' 
        # collect all the '.'s together into the namespace
        tag_namespace = '.'.join(tag_parts[:-1])
        tag_name = tag_parts[-1]

    tag_value = tag_and_value[1]

    # first manage the tag ... 
    tag_dict = { 
               'namespace' : tag_namespace,
               'name'      : tag_name,
               'value'     : tag_value,
               }   

    query = sdnsh.rest_query_objects('tag', tag_dict)
    sdnsh.check_rest_result(query)
    tag_dict['persist'] = True
    if len(query) == 0:
        result = sdnsh.rest_create_object('tag', tag_dict)
        sdnsh.check_rest_result(result)
    elif len(query) == 1:
        update = sdnsh.rest_update_object('tag',
                                          mi.pk('tag'),
                                          query[0][mi.pk('tag')],
                                          tag_dict)
        sdnsh.check_rest_result(update)

    del tag_dict['persist']
    query = sdnsh.rest_query_objects('tag', tag_dict)
    sdnsh.check_rest_result(query)
    tag_id = query[0][mi.pk('tag')]

    # now create the tag-mapping
    tag_dict = { 
               fk    : sdnsh.get_current_mode_obj(), # fk from early for loop
               'tag' : tag_id,
               }   

    query = sdnsh.rest_query_objects(obj_type, tag_dict)
    sdnsh.check_rest_result(query)
    if len(query) == 0:
        result = sdnsh.rest_create_object(obj_type, tag_dict)
        sdnsh.check_rest_result(result)


def command_delete_tag(obj_type, data):
    """
    obj_type describes the tag-XXX-mapping which is getting
    managed, data has the tag 'string' to delete.
    """
    item = sdnsh.get_current_mode_obj_type()
    fks = mi.obj_type_foreign_keys(obj_type)
    for fk in fks:
        (fk_obj, fk_name) = mi.foreign_key_references(obj_type, fk)
        if fk_obj == item:
            break
    else:
        raise error.CommandSemanticError( "type mapping %s doesn't have "
                        "relationship to the current object %s" %
                        (obj_type, item))

    if 'tag' not in data:
        raise error.CommandSemanticError('Tag value missing')

    tag = data['tag']
    name_and_value = tag.split('=')

    name_part = name_and_value[0].split('.')
    if len(name_part) == 1:
        namespace = 'default'
        name = name_part[0]
    elif len(name_part) >= 2:
        namespace = '.'.join(name_part[:-1])
        name = name_part[-1]

    value = name_and_value[1]
    pk_value = sdnsh.unique_key_from_non_unique([namespace,
                                                 name,
                                                 value,
                                                 sdnsh.get_current_mode_obj()])
    try:
        sdnsh.get_object_from_store(obj_type, pk_value)
    except Exception:
        raise error.CommandSemanticError('%s No such tag %s' % (obj_type, tag))

    sdnsh.rest_delete_object(obj_type, pk_value)

    # with that entry removed, check to see if any other
    # foreign keys assocaited with class Tag exist.

    fk_value = sdnsh.unique_key_from_non_unique([namespace,
                                                 name,
                                                 value])

    for tag_fields in mi.foreign_key_xref['tag']:
        for (fk_obj_type, fk_name) in mi.foreign_key_xref['tag'][tag_fields]:
            try:
                sdnsh.get_table_from_store(fk_obj_type, fk_name, fk_value)
                break
            except Exception, e:
                pass
        else:
            continue
        break
    else:
        try:
            sdnsh.rest_delete_object('tag', fk_value)
        except Exception, e:
            raise error.CommandSemanticError('base tag missing' % fk_value)


def command_rest_post_data(path, data=None, verb='PUT'):
    """
    """
    url = 'http://%s/rest/v1/%s' % (sdnsh.controller, path)
    result = sdnsh.rest_post_request(url, data, verb)
    check_rest_result(result)
    return None


def command_cli_variables_set(variable, value, data):
    global sdnsh

    if variable == 'debug':
        print '***** %s cli debug *****' % \
                ('Enabled' if value else 'Disabled')
        sdnsh.debug = value
    elif variable == 'cli-backtrace':
        print '***** %s cli debug backtrace *****' % \
                ('Enabled' if value else 'Disabled')
        sdnsh.debug_backtrace = value
    elif variable == 'cli-batch':
        print '***** %s cli batch mode *****' % \
                ('Enabled' if value else 'Disabled')
        sdnsh.batch = value
    elif variable == 'description':
        print '***** %s command description mode *****' % \
                ('Enabled' if value else 'Disabled')
        sdnsh.description = value
    elif variable == 'rest':
        if 'record' in data and value:
            print '***** Eanbled rest record mode %s *****' % \
                (data['record'])
            url_cache.record(data['record'])
            return
        print '***** %s display rest mode *****' % \
                ('Enabled' if value else 'Disabled')
        if 'detail' in data and data['detail'] == 'details':
            if value == True:
                sdnsh.disply_rest_detail = value
                sdnsh.store.display_reply_mode(value)
        sdnsh.display_rest = value
        sdnsh.store.display_mode(value)
        if value == False:
            sdnsh.disply_rest_detail = value
            sdnsh.store.display_reply_mode(value)
            url_cache.record(None)
    elif variable == 'set':
        if 'length' in data:
            sdnsh.length = utif.try_int(data['length'])


def command_cli_set(variable, data):
    command_cli_variables_set(variable, True, data)

def command_cli_unset(variable, data):
    command_cli_variables_set(variable, False, data)


def command_shell_command(script):

    def shell(args):
        subprocess.call(["env", "SHELL=/bin/bash", "/bin/bash"] + list(args),
                        cwd=os.environ.get("HOME"))
        print

    print "\n***** Warning: this is a debug command - use caution! *****"
    if script == 'bash':
        print '***** Type "exit" or Ctrl-D to return to the CLI *****\n'
        shell(["-l", "-i"])
    elif script == 'python':
        print '***** Type "exit()" or Ctrl-D to return to the CLI *****\n'
        shell(["-l", "-c", "python"])
    elif script == 'cassandra-cli':
        print '***** Type "exit" or Ctrl-D to return to the CLI *****\n'
        shell(["-l", "-c", "/opt/sdnplatform/db/bin/cassandra-cli --host localhost"])
    elif script == 'netconfig':
        if not re.match("/dev/ttyS?[\d]+$", os.ttyname(0)):
            print '***** You seem to be connected via SSH or another remote protocol;'
            print '***** reconfiguring the network interface may disrupt the connection!'
        print '\n(Press Control-C now to leave the network configuration unchanged)\n'
        subprocess.call(["sudo",
                         "env",
                         "SHELL=/bin/bash",
                         "/opt/sdnplatform/sys/bin/bscnetconfig",
                         "eth0"],
                         cwd=os.environ.get("HOME"))
    else:
        # XXX possibly run the script directly?
        print "Unknown debug choice %s" % script


def command_prompt_update():
    """
    Action to recompute the prompt, used when there's some possibility
    the prompt has changes after some other action (hostname update, for example)
    """
    sdnsh.set_controller_for_prompt()
    sdnsh.update_prompt()

def command_controller_decommission(data):
    """
    Decommission the controller using the REST API
    """
    id = data.get('id')
    confirm_request("Decommission controller '%s'?\n(yes to continue) " % id)

    while True:
        url = 'http://%s/rest/v1/system/ha/decommission' % (sdnsh.controller)
        result = sdnsh.rest_post_request(url, {"id": id}, 'PUT')
        status = json.loads(result)

        if (status['status'] == 'OK') and status['description'].endswith('is already decommissioned') == True:
            print 'Decommission finished'
            print
            break
        else:
            print 'Decommission in progress'
            
        time.sleep(10)

def command_controller_upgrade(data = None):
    """
    Upgrade the controller using the REST API
    """

    force = 'force' in data
    details = 'details' in data

    if force:
        print "WARNING: Ignoring any validation errors during upgrade"
    url = "http://%s/rest/v1/system/upgrade/image-name" % sdnsh.controller
    result = sdnsh.store.rest_simple_request(url)
    check_rest_result(result)
    iname = json.loads(result)
    if (iname['file'] is None or iname['file'] == ""):
        print "Error: No upgrade image present."
        print ""
        print """To perform upgrade, an upgrade image package needs to be uploaded (with scp) to the controller's \"images\" user."""
        print """Upgrade image package is a file with name of format \"upgrade-YYYY.MM.DD.XXXX.pkg\"."""
        print ""
        print "Following is an example to prepare upgrade for controller with IP address 192.168.67.141:"
        print "scp $path/upgrade-2013.02.13.0921.pkg images@192.168.67.141:"
        print ""
        return

    confirm_request("Upgrade controller from image '%s'?\n(yes to continue) "
                    % iname['file'])
    
    url = "http://%s/rest/v1/system/upgrade/extract-image-manifest" % sdnsh.controller
    result = sdnsh.store.rest_simple_request(url)
    check_rest_result(result)
    manifest = json.loads(result)

    print "Executing upgrade..."
    for step in manifest:
        print "%s - %s" % (step['step'], step['description'])
        url = 'http://%s/rest/v1/system/upgrade/execute-upgrade-step' % \
            (sdnsh.controller)
        result = sdnsh.rest_post_request(url, {"step": step['step'],
                                               "imageName": iname['file'],
                                               "force": force}, 
                                         'PUT')
        check_rest_result(result)
        status = json.loads(result)
        
        if (status['status'] == "OK"):
            print "  Succeeded"
            if details:
                print "\nDetailed output:"
                print status['description']
                print
        else:
            print "  Failed to execute upgrade step %d" % step['step']
            print "\nDetailed output:"
            print status['description']
            print
            return

    print """Controller node upgrade complete.
Upgrade will not take effect until system is rebooted. Use 'reload' to
reboot this controller node. To revert, select the appropriate image 
from the boot menu"""

def command_cluster_config_rollback(data):
    path = ''
    if data.get('dir') == 'images://':
        path += '/home/images/'
    elif data.get('dir') == 'saved-configs://':
        path += '/opt/sdnplatform/run/saved-configs/'
    path += data.get('file')

    url = "http://%s/rest/v1/system/ha/role" % sdnsh.controller
    result = sdnsh.store.rest_simple_request(url, use_cache = False)
    ha_role = json.loads(result)
    if ha_role['role'] != 'MASTER':
        print "Command can only be run on Master"
        return
   
    command_legacy_cli('copy', {'dest': 'file://running-config-copy', 'source': 'running-config'})
    print "INFO: Checking config '%s'" % path
    url = "http://%s/rest/v1/system/rollback/diffconfig" % sdnsh.controller
    result = sdnsh.rest_post_request(url, {"config-1": "/opt/sdnplatform/run/saved-configs/running-config-copy", "config-2": path}, 'PUT')
    check_rest_result(result)
    if json.loads(result)['out'].startswith('Found differences'):
        print json.loads(result)['out']
        print "Rollback aborted"
        return
        
    url = "http://%s/rest/v1/system/controller" % sdnsh.controller
    result = sdnsh.store.rest_simple_request(url, use_cache = False)
    controller_id = json.loads(result)['id']

    url = "http://%s/rest/v1/model/controller-interface?controller=%s" % (sdnsh.controller, controller_id)
    result = sdnsh.store.rest_simple_request(url)
    local_iface = json.loads(result)[0]['discovered-ip']
    
    url = "http://%s/rest/v1/model/controller-interface" % sdnsh.controller
    result = sdnsh.store.rest_simple_request(url)
    check_rest_result(result)
    ifaces = json.loads(result)

    nodeCount = len(ifaces)
    cutover = nodeCount/2
    if nodeCount%2 == 1:
        cutover = cutover + 1
    
    rollbackedNodes = []

    # remove and add object for local node at the end of the list
    for index, iface in enumerate(ifaces):
        if iface['discovered-ip'] == local_iface:
            break
    del ifaces[index]
    ifaces.append(iface)

    config=open(path, 'r').read()
    url = 'http://%s/rest/v1/system/upload-data' % ifaces[0]['discovered-ip']
    result = sdnsh.rest_post_request(url, {"data": config, "dst" : "/tmp/rollback.conf"}, 'PUT')
    check_rest_result(result)
    
    while len(ifaces) > 0:
        if sdnsh.batch == False:
            while True:
                confirm = raw_input("Rollback controller at '%s'. [yes/no] ?" % ifaces[0]['discovered-ip'])
                if confirm.lower() == 'n' or confirm.lower() == 'no':
                    if len(rollbackedNodes) == 0:
                        print "INFO: Rollback aborted"
                        return
                        
                    print "INFO: Undoing Rollback on previously rollbacked nodes"
                    for node in rollbackedNodes:
                        print "INFO: Resetting database on '%s'" % node['discovered-ip']
                        url = 'http://%s/rest/v1/system/resetbsc' % (node['discovered-ip'])
                        result = sdnsh.rest_post_request(url, {}, 'PUT')
                        check_rest_result(result)
                        print "INFO: Rebooting '%s'" % node['discovered-ip']
                        url = 'http://%s/rest/v1/system/reload' % (node['discovered-ip'])
                        result = sdnsh.rest_post_request(url, {}, 'GET')
                        check_rest_result(result)
                    
                    if len(rollbackedNodes) >= cutover:
                        # delete the REJECT rules
                        url="http://localhost/rest/v1/model/firewall-rule?port=6633"
                        result = sdnsh.rest_post_request(url, {}, 'DELETE')
                        # enable allow openflow on all controllers not rollbacked.
                        url="http://localhost/rest/v1/model/firewall-rule"
                        for iface in ifaces:
                            pk_id = '%s|Ethernet|0' % iface['controller']
                            data = {
                                'action': 'allow',
                                'interface': pk_id,
                                'src-ip': '',
                                'port': '6633',
                                'proto': 'tcp',
                                'vrrp-ip': '',
                            }
                            print "INFO: re-allow openflow on %s" % iface['discovered-ip']
                            result = sdnsh.rest_post_request(url, data, 'PUT')
                            check_rest_result(result)
                    
                    print "Rollback aborted"
                    return
                elif confirm.lower() == 'y' or confirm.lower() == 'yes':
                    break
        
        url = 'http://%s/rest/v1/system/rollback/config' % (ifaces[0]['discovered-ip'])
        result = sdnsh.rest_post_request(url, {"path": "/tmp/rollback.conf"}, 'PUT')
        check_rest_result(result)
        time.sleep(10)
       
        print "INFO: Rebooting ", ifaces[0]['discovered-ip']
        url = "http://%s/rest/v1/system/reload" % ifaces[0]['discovered-ip']
        result = sdnsh.store.rest_simple_request(url)
        
        if ifaces[0]['discovered-ip'] == local_iface:
            break
        
        print "INFO: Waiting for %s to come back up" % ifaces[0]['discovered-ip']
        url = "http://%s/rest/v1/system/ha/role" % ifaces[0]['discovered-ip']
        while True:
            time.sleep(30)
            try:
                result = sdnsh.store.rest_simple_request(url, use_cache = False)
                status = json.loads(result)
                if status['role'] == 'SLAVE' or status['role'] == 'MASTER':
                    print "INFO: Rollback complete on '%s'" % ifaces[0]['discovered-ip']
                    break
                print "INFO: Waiting for 30 seconds" 
            except:
                print "INFO: Waiting for 30 seconds" 
                
         
        iface = ifaces.pop(0)
        rollbackedNodes.append(iface)

    print "Rollback completed"

def command_wait_for_controller(delay = None, sdnplatform_check = False,
                                within_command = False):
    """
    For various commands, it makes sense for the command to verify that
    the controller restart has been completed.   In the situation where
    a single controller is configured, it also makes sense to verify the
    controller is now configured as MASTER.

    This is especially true for command which are known to cause the
    controller to restart, for exampe the 'feature' command.

    The procedure is also used during CLI startup (see cli.py)
    to verify that the controller is in MASTER mode.  Its normal
    for the HA role to transition from SLAVE to master during 
    system startup.
    """

    # if the CLI was started with --init, skip the wait, the
    # controller isn't running.
    if sdnsh.options.init:
        return
    
    def is_ready(sdnsh, verbose, duration):
        """
        Be loud-as-_ean when the duration is greater then 15 seconds.
        Display the gory details for all to know.
        """
        too_long = 90
        try:
            url = "http://%s/rest/v1/system/ha/role" % sdnsh.controller
            result = sdnsh.store.rest_simple_request(url, use_cache = False)
            ha_role = json.loads(result)
            if duration > too_long:
                print 'Long delay: reason', \
                    ', '.join(['%s: %s' % (n,v) for (n,v) in ha_role.items()
                               if v != ''])
            if (ha_role['role'] == 'MASTER' or
                sdnsh.find_master()['master'] is not None):
                if verbose:
                    print 'Current role is MASTER'
                return True
            return False
        except error.CommandRestError,e:
            print "REST error whileUnable to determine controller HA role."
            errors = self.rest_error_to_dict(e, obj_type)
            print self.rest_error_dict_to_message(errors)
            return True
        except Exception, e:
            if duration > too_long:
                print 'MASTER Transition Failure: ', e
                traceback.print_exc()
                return True
            return False

    # if this isn't a typical environment (ie: running remotely)
    # don't bother trying to determine the role
    if not os.path.exists('/opt/sdnplatform/current_role'):
        return
    
    # now vadalidate the rest api port is working 
    ip_and_port = sdnsh.controller.split(':')
    if len(ip_and_port) == 2:
        # first ensure the REST API is answering
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            s.connect((ip_and_port[0], int(ip_and_port[1])))
            s.close()
        except Exception, e:
            print 'REST API not running, emergency CLI access'
            if sdnsh.debug: # enable debug to see messages
                print 'Exception:', e
            return

    # issue a REST API request directed at the model.
    try:
        entry = sdnsh.get_table_from_store('feature')
    except Exception, e:
        print 'REST API/Database not responding, emergency CLI access'
        if sdnsh.debug: # enable debug to see messages
            print 'Exception:', e
        return 
    
    if sdnplatform_check:
        # the REST API request for ha-role will return UNAVAILABLE
        # when sdnplatform isn't running.
        url = "http://%s/rest/v1/system/ha/role" % sdnsh.controller
        result = sdnsh.store.rest_simple_request(url, use_cache = False)
        ha_role = json.loads(result)
        if ha_role['role'] == 'UNAVAILABLE':
            print 'REST API/SDN platform not responding, emergency CLI access'
            return 


    if delay == None:
        delay = 1
    delay_str = 'a sec' if delay == 1 else '%d seconds' % delay

    duration = 0
    while True:
        try:
            verbose = False
            while not is_ready(sdnsh, verbose, duration):
                if within_command:
                    print 'Waiting %s to complete command execution, ' \
                          'Hit Ctrl-C to exit early' % delay_str
                    verbose = False
                else:
                    print 'Waiting %s while current role is SLAVE mode, ' \
                          'Hit Ctrl-C to exit early' % delay_str
                    verbose = True
                time.sleep(delay)
                duration += delay
            return
        except:
            if is_ready(sdnsh, True, duration):
                if duration > 15:
                    print 'MASTER Transition: %s sec' % duration
                return
            try:
                resp = raw_input('Controller is not yet ready.'
                                 'Do you still want to continue to the CLI? [n]')
                if resp and "yes".startswith(resp.lower()):
                    print 'Continuing with CLI despite initialization error ...'
                    return
            except KeyboardInterrupt:
                return


def command_factory_default():
    print "Re-setting controller to factory defaults ..."
    os.system("sudo /opt/sdnplatform/sys/bin/resetbsc")
    return


def command_dump_log(data):
    controller = data.get('controller-node') # can be None.
    controller_dict = { 'id' : controller }
    for ip_port in controller_ip_and_port(controller_dict):
        log_name = data['log-name']
        if log_name == 'all':
            url = log_url(ip_and_port = ip_port)
            log_names = command.sdnsh.rest_simple_request_to_dict(url)
            for log in log_names:
                yield '*' * 40 + ip_port + ' ' + log['log'] + '\n'
                for item in command_dump_log({ 'log-name' : log['log'] }):
                    yield item
            return

        # use a streaming method so the complete log is not in memory
        url = log_url(ip_and_port = ip_port, log = log_name)
        request = urllib2.urlopen(url)
        for line in request:
            yield line
        request.close()


#
# Initialize action functions 
#
#

def init_actions(bs, modi):
    global sdnsh, mi
    sdnsh = bs
    mi = modi

    command.add_action('create-tunnel',
                       tunnel_create,
                       {'kwargs': {'data' : '$data',}})

    command.add_action('remove-tunnel',
                       tunnel_remove,
                       {'kwargs': {'data' : '$data',}})

    command.add_action('create-policy',
                       policy_create,
                       {'kwargs': {'data' : '$data',}})
    
    command.add_action('remove-policy',
                       policy_remove,
                       {'kwargs': {'data' : '$data',}})
    
    command.add_action('write-fields', write_fields,
                       {'kwargs': {'obj_type': '$current-mode-obj-type',
                                   'obj_id': '$current-mode-obj-id',
                                   'data': '$data'}})

    command.add_action('reset-fields', reset_fields,
                       {'kwargs': {'obj_type'     : '$current-mode-obj-type',
                                   'obj_id'       : '$current-mode-obj-id',
                                   'arg_data'     : '$data',
                                   'match_for_no' : '$match-for-no',
                                   'fields'       : '$fields'}})

    command.add_action('write-fields-explicit', write_fields,
                       {'kwargs': {'obj_type' : '$obj-type',
                                   'obj_id'   : '$obj-id',
                                   'data'     : '$data'}})

    command.add_action('reset-fields-explicit', reset_fields,
                       {'kwargs': {'obj_type'     : '$obj-type',
                                   'obj_id'       : '$obj-id',
                                   'arg_data'     : '$data',
                                   'match_for_no' : '$match-for-no',
                                   'fields'       : '$fields'}})

    command.add_action('update-config', update_config,
                       {'kwargs': {'obj_type'      : '$obj-type',
                                   'obj_id'        : '$current-mode-obj-id',
                                   'data'          : '$data',
                                   'no_command'    : '$is-no-command', }})

    command.add_action('delete-objects', delete_objects,
                       {'kwargs': {'obj_type': '$obj-type',
                                   'data': '$data',
                                   'parent_field': '$parent-field',
                                   'parent_id': '$current-mode-obj-id'}})

    command.add_action('write-object', write_object,
                       {'kwargs': {'obj_type': '$obj-type',
                                   'data': '$data',
                                   'parent_field': '$parent-field',
                                   'parent_id': '$current-mode-obj-id'}})
        
    command.add_action('set-data', set_data,
                       {'kwargs': {'data': '$data',
                                   'key': '$key',
                                   'value': '$value'}})

    command.add_action('push-mode-stack', push_mode_stack,
                       {'kwargs': {'mode_name': '$submode-name',
                                   'obj_type': '$obj-type',
                                   'parent_field': '$parent-field',
                                   'parent_id': '$current-mode-obj-id',
                                   'data': '$data',
                                   'create': '$create'}})

    command.add_action('pop-mode-stack', pop_mode_stack)

    command.add_action('confirm', confirm_request,
                        {'kwargs': {'prompt': '$prompt'}})

    command.add_action('convert-vns-access-list', convert_vns_access_list,
                        {'kwargs': {'obj_type': '$obj-type',
                                    'key' : '$current-mode-obj-id',
                                    'data' : '$data'}})
    command.add_action('display-table', command_display_table,
                        {'kwargs': {'obj_type'      : '$obj-type',
                                    'data'          : '$data',
                                    'table_format'  : '$format',
                                    'title'         : '$title',
                                    'detail'        : '$detail',
                                    'scoped'        : '$scoped',
                                    'sort'          : '$sort',
                                   }})

    command.add_action('display-rest', command_display_rest,
                        {'kwargs': { 'data'          : '$data',
                                     'url'           : '$url',
                                     'path'          : '$path',
                                     'rest_type'     : '$rest-type',
                                     'sort'          : '$sort',
                                     'title'         : '$title',
                                     'table_format'  : '$format',
                                     'detail'        : '$detail',
                                   }})

    command.add_action('query-table', command_query_table,
                        {'kwargs': {'obj_type'      : '$obj-type',
                                    'data'          : '$data',
                                    'key'           : '$key',
                                    'scoped'        : '$scoped',
                                    'sort'          : '$sort',
                                    'crack'         : '$crack',
                                    'append'        : '$append',
                                    'clear'         : True,
                                   }})

    command.add_action('query-table-append', command_query_table,
                        {'kwargs': {'obj_type'      : '$obj-type',
                                    'data'          : '$data',
                                    'key'           : '$key',
                                    'scoped'        : '$scoped',
                                    'sort'          : '$sort',
                                    'crack'         : '$crack',
                                    'append'        : '$append',
                                    'clear'         : False,
                                   }})


    command.add_action('query-rest', command_query_rest,
                        {'kwargs': {'url'           : '$url',
                                    'path'          : '$path',
                                    'rest_type'     : '$rest-type',
                                    'data'          : '$data',
                                    'key'           : '$key',
                                    'scoped'        : '$scoped',
                                    'sort'          : '$sort',
                                    'append'        : '$append',
                                    'clear'         : True,
                                   }})

    command.add_action('query-rest-append', command_query_rest,
                        {'kwargs': {'url'           : '$url',
                                    'path'          : '$path',
                                    'rest_type'     : '$rest-type',
                                    'data'          : '$data',
                                    'key'           : '$key',
                                    'scoped'        : '$scoped',
                                    'sort'          : '$sort',
                                    'crack'         : '$crack',
                                    'append'        : '$append',
                                    'clear'         : False,
                                   }})

    command.add_action('join-rest', command_join_rest,
                        {'kwargs': {'url'           : '$url',
                                    'key'           : '$key',
                                    'join_field'    : '$join-field',
                                    'rest_type'     : '$rest-type',
                                    'add_field'     : '$add-field',
                                    'data'          : '$data',
                                    'crack'         : '$crack',
                                    'url_key'       : '$url-key',
                                   }})

    command.add_action('join-table', command_join_table,
                        {'kwargs': {'obj_type'      : '$obj-type',
                                    'data'          : '$data',
                                    'key'           : '$key',
                                    'key_value'     : '$key-value',
                                    'add_field'     : '$add-field',
                                    'join_field'    : '$join-field',
                                    'crack'         : '$crack',
                                   }})

    command.add_action('crack', command_crack,
                        {'kwargs': {
                                    'field'         : '$field',
                                   }})

    command.add_action('display', command_display,
                        {'kwargs': {'data'         : '$data',
                                    'table_format' : '$format',
                                    'sort'         : '$sort',
                                    'detail'       : '$detail',
                                    'title'        : '$title',
                                   }})

    command.add_action('legacy-cli', command_legacy_cli,
                        {'kwargs': {'obj_type' : '$obj-type',
                                    'data'     : '$data',
                                    'detail'   : '$detail',
                                    'sort'     : '$sort',
                                    'scoped'   : '$scoped',
                                   }})

    command.add_action('legacy-cli-no', command_legacy_cli_no,
                        {'kwargs': {'obj_type' : '$obj-type',
                                    'data'     : '$data',
                                    'detail'   : '$detail',
                                    'sort'     : '$sort',
                                    'scoped'   : '$scoped',
                                   }})

    command.add_action('version',  command_version,
                        {'kwargs': {'data' : '$data',
                                   }})

    command.add_action('clearterm',  command_clearterm)

    command.add_action('display-cli',  command_display_cli,
                        {'kwargs': {'data'   : '$data',
                                    'detail' : '$detail',
                                   }})

    command.add_action('create-alias', command_create_alias,
                        {'kwargs': {'obj_type' : '$obj-type',
                                    'data'     : '$data',
                                    'reserved' : '$reserved',
                                    'fail_if_exists' : '$fail-if-exists',
                                   }})

    command.add_action('delete-alias', command_delete_alias,
                        {'kwargs': {'obj_type' : '$obj-type',
                                    'data'   : '$data',
                                   }})

    command.add_action('create-tag', command_create_tag,
                        {'kwargs': {'obj_type' : '$obj-type',
                                    'data'   : '$data',
                                   }})

    command.add_action('delete-tag', command_delete_tag,
                        {'kwargs': {'obj_type' : '$obj-type',
                                    'data'   : '$data',
                                   }})
 
    command.add_action('cli-set', command_cli_set,
                        {'kwargs': {'variable' : '$variable',
                                    'data'     : '$data',
                                   }})

    command.add_action('cli-unset', command_cli_unset,
                        {'kwargs': {'variable' : '$variable',
                                    'data'     : '$data',
                                   }})

    command.add_action('shell-command', command_shell_command,
                        {'kwargs': {'script' : '$command',
                                   }})
    
    command.add_action('rest-post-data', command_rest_post_data,
                        {'kwargs': {'path': '$path',
                                    'data': '$data',
                                    'verb': '$verb'
                                    }})

    command.add_action('prompt-update', command_prompt_update,)

    command.add_action('controller-upgrade', command_controller_upgrade,
                       {'kwargs': {'data': '$data'}})
    
    command.add_action('controller-config-rollback', command_cluster_config_rollback,
                       {'kwargs': {'data': '$data'}})
    
    command.add_action('controller-decommission', command_controller_decommission,
                       {'kwargs': {'data': '$data'}})

    command.add_action('wait-for-controller', command_wait_for_controller,
                       {'kwargs': {'within_command': True}})

    command.add_action('factory-default', command_factory_default)

    command.add_action('dump-log', command_dump_log,
                        {'kwargs' : { 'data' : '$data', }})
