#
# Copyright (c) 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.
#

from django.db.models import AutoField, BooleanField, IntegerField, FloatField, ForeignKey
from django.forms import ValidationError
from django.http import HttpResponse
from django.utils import simplejson
from functools import wraps
from sdncon.controller.models import Controller
#from sdncon.controller.models import ControllerAlias, ControllerDomainNameServer, ControllerInterface, FirewallRule
from sdncon.controller.models import Switch, Port, PortAlias, Link
from sdncon.rest.models import UserData
from sdncon.controller.notification import begin_batch_notification, end_batch_notification
from django.views.decorators.csrf import csrf_exempt
import base64
import urllib
import urllib2
import sys
import json
import os
import re
import time
import traceback
import collections
import uuid
import subprocess
from datetime import datetime
from sdncon.controller.oswrapper import exec_os_wrapper
from sdncon.controller.config import get_local_controller_id
from sdncon.rest.config import config_check_state
from sdncon.controller.oswrapper import get_system_version_string
import sdncon

TEXT_PLAIN_CONTENT_TYPE = 'text/plain'
TEXT_JAVASCRIPT_CONTENT_TYPE = 'text/javascript'
JSON_CONTENT_TYPE = 'application/json'
BINARY_DATA_CONTENT_TYPE = 'application/octet-stream'

onos = 1

if onos == 1:
    #CONTROLLER_URL_PREFIX = 'http://localhost:9000/wm/'
    CONTROLLER_URL_PREFIX = 'http://localhost:8080/wm/'
else:
    CONTROLLER_URL_PREFIX = 'http://localhost:8080/wm/'

def controller_url(*elements):
    return CONTROLLER_URL_PREFIX + '/'.join(elements)

class RestException(Exception):
    pass
        
class RestInvalidDataTypeException(RestException):
    def __init__(self, name):
        super(RestInvalidDataTypeException,self).__init__('Invalid data type: ' + name)

class RestInvalidMethodException(RestException):
    def __init__(self):
        super(RestInvalidMethodException,self).__init__('Invalid HTTP method')

class RestResourceNotFoundException(RestException):
    def __init__(self, url):
        super(RestResourceNotFoundException,self).__init__('Resource not found: ' + url)

class RestDatabaseConnectionException(RestException):
    def __init__(self):
        super(RestDatabaseConnectionException,self).__init__('Error connecting to database')
        
class RestAuthenticationRequiredException(RestException):
    def __init__(self):
        super(RestAuthenticationRequiredException,self).__init__('Authentication required')

class RestInvalidQueryParameterException(RestException):
    def __init__(self, param_name):
        super(RestInvalidQueryParameterException, self).__init__('Invalid query parameter: ' + str(param_name))

class RestInvalidFilterParameterException(RestException):
    def __init__(self, param_name):
        super(RestInvalidFilterParameterException, self).__init__('Filter query parameters not allowed when URL contains resource iD: ' + str(param_name))

class RestNoListResultException(RestException):
    def __init__(self):
        super(RestNoListResultException, self).__init__('The query result must be a single instance if the "nolist" query param is set')

class RestInvalidPutDataException(RestException):
    def __init__(self):
        super(RestInvalidPutDataException, self).__init__('The request data for a PUT request must be a JSON dictionary object')

class RestMissingRequiredQueryParamException(RestException):
    def __init__(self, param_name):
        super(RestMissingRequiredQueryParamException, self).__init__('Missing required query parameter: ' + str(param_name))

class RestValidationException(RestException):
    def __init__(self, model_error=None, field_errors=None):
        # Build the exception message from model error and field errors
        message = 'Validation error'
        if model_error:
            message = message + '; ' + model_error
        if field_errors:
            message += '; invalid fields: {'
            first_time = True
            for field_name, field_message in field_errors.items():
                if not first_time:
                    message += '; '
                else:
                    first_time = False
                message = message + field_name + ': ' + field_message
                
            message += '}'
            
        super(RestValidationException, self).__init__(message)
        self.model_error = model_error
        self.field_errors = field_errors
        
class RestModelException(RestException):
    def __init__(self, exc):
        super(RestModelException, self).__init__('Error: ' + str(exc))

class RestSaveException(RestException):
    def __init__(self, exc):
        super(RestSaveException, self).__init__('Error saving data: ' + str(exc))

class RestInvalidOrderByException(RestException):
    def __init__(self,field_name):
        super(RestInvalidOrderByException, self).__init__('Invalid orderby field: ' + field_name)
        
class RestInternalException(RestException):
    def __init__(self, exc):
        super(RestInternalException,self).__init__('Unknown REST error: ' + unicode(exc))

class RestUpgradeException(RestException):
    def __init__(self, exc):
        super(RestUpgradeException, self).__init__('Error: ' + str(exc))

class RestProvisionException(RestException):
    def __init__(self, exc):
        super(RestProvisionException, self).__init__('Error: ' + str(exc))

class RestDecommissionException(RestException):
    def __init__(self, exc):
        super(RestDecommissionException, self).__init__('Error: ' + str(exc))

class RestInvalidLog(RestException):
    def __init__(self, exc):
        super(RestInvalidLog, self).__init__('Error: ' + str(exc))

def handle_validation_error(model_info, validation_error):
    model_error = None
    field_errors = None
    if hasattr(validation_error, 'message_dict'):
        # The field errors we get in the ValidationError are a bit different
        # then what we want for the RestValidationException. First, we
        # need to convert the Django field name to the (possibly renamed)
        # REST field name. Second, the per-field error message is possibly a
        # list of messages, which we concatenate into a single string for the
        # RestValidationException
        for field_name, field_message in validation_error.message_dict.items():
            if type(field_message) in (list, tuple):
                converted_field_message = ''
                for msg in field_message:
                    converted_field_message = converted_field_message + msg + ' '
            else:
                converted_field_message += unicode(field_message)
            if field_name == '__all__':
                model_error = converted_field_message
            else:
                if not field_errors:
                    field_errors = {}
                field_info = model_info.field_name_dict.get(field_name)
                if field_info:
                    field_errors[field_info.rest_name] = converted_field_message
                else:
                    field_errors[field_name] = 'Private field invalid; ' + converted_field_message
    elif hasattr(validation_error, 'messages'):
        model_error = ':'.join(validation_error.messages)
    else:
        model_error = str(validation_error)
    raise RestValidationException(model_error, field_errors)

def get_successful_response(description=None, status_code=200):
    content = get_successful_response_data(description)
    return HttpResponse(content, JSON_CONTENT_TYPE, status_code)

def get_successful_response_data(description = 'success'):
    obj = {'description': description}
    return simplejson.dumps(obj)
 
def get_sdnplatform_response(url, timeout = None):
    
    try:
        response_text = urllib2.urlopen(url, timeout=timeout).read()
        return HttpResponse(response_text, JSON_CONTENT_TYPE)
    except urllib2.HTTPError, e:
        response_text = e.read()
        response = simplejson.loads(response_text)
        response['error_type'] = "SDNPlatformError"
        return HttpResponse(content=simplejson.dumps(response), 
                            status=e.code, 
                            content_type=JSON_CONTENT_TYPE)

def get_sdnplatform_query(request, path):
    """
    This returns controller-level storage table list
    """
    if request.method != 'GET':
        raise RestInvalidMethodException()
    url = controller_url(path) + '/?%s' % request.META['QUERY_STRING']
    return get_sdnplatform_response(url)        

def safe_rest_view(func):
    """
    This is a decorator that takes care of exception handling for the
    REST views so that we return an appropriate error HttpResponse if
    an exception is thrown from the view
    """
    @wraps(func)
    def _func(*args, **kwargs):
        try:
            response = func(*args, **kwargs)
        except Exception, exc:
            end_batch_notification(True)
            if not isinstance(exc, RestException):
                # traceback.print_exc()
                exc = RestInternalException(exc)
            response_obj = {'error_type': exc.__class__.__name__, 'description': unicode(exc)}
            if isinstance(exc, RestValidationException):
                if exc.model_error:
                    response_obj['model_error'] = exc.model_error
                if exc.field_errors:
                    response_obj['field_errors'] = exc.field_errors
            content = simplejson.dumps(response_obj)
            content_type = JSON_CONTENT_TYPE
            
            if isinstance(exc, RestInvalidMethodException):
                status_code = 405
            elif isinstance(exc, RestResourceNotFoundException):
                status_code = 404
            elif isinstance(exc, RestInternalException):
                status_code = 500
            else:
                status_code = 400
            response = HttpResponse(content, content_type, status_code)
            if isinstance(exc, RestInvalidMethodException):
                response['Allow'] = "GET, PUT, DELETE"
        return response
    return _func

rest_model_info_dict = {}

class RestFieldInfo(object):
    def __init__(self, name, django_field_info, hidden=False,
                 rest_name=None, json_serialize=False):
        self.name = name
        self.django_field_info = django_field_info
        self.rest_name = rest_name
        self.json_serialize = json_serialize
        
class RestModelInfo(object):
    def __init__(self, rest_name, model_class):
        self.rest_name = rest_name
        self.model_class = model_class
        self.primary_key = None
        self.field_name_dict = {}
        self.rest_name_dict = {}
        
        for field in model_class._meta.local_fields:
            field_name = field.name
            rest_name = field.name
            if field.primary_key:
                self.primary_key = field_name
            # TODO: Are there other field types that should be included here?
            json_serialize =  type(field) not in (AutoField, BooleanField, IntegerField, FloatField)
            self.set_field_info(field_name, rest_name, field, json_serialize)

    
    # this is how a RestFieldInfo is created - pass in django_field_info
    def get_field_info(self, field_name, django_field_info=None):
        field_info = self.field_name_dict.get(field_name)
        if not field_info and django_field_info:
            field_info = RestFieldInfo(field_name, django_field_info)
            self.field_name_dict[field_name] = field_info
        return field_info
    
    def hide_field(self, field_name):
        field_info = self.get_field_info(field_name)
        del self.field_name_dict[field_name]
        del self.rest_name_dict[field_info.rest_name]
        
    def set_field_info(self, field_name, rest_name, django_field_info, json_serialize=None):
        field_info = self.get_field_info(field_name, django_field_info)
        if field_info.rest_name in self.rest_name_dict:
            del self.rest_name_dict[field_info.rest_name]
        field_info.rest_name = rest_name
        if json_serialize != None:
            field_info.json_serialize = json_serialize
        self.rest_name_dict[rest_name] = field_info

def get_rest_model_info(name):
    return rest_model_info_dict[name]

def add_rest_model_info(info):
    if rest_model_info_dict.get(info.rest_name):
        raise RestException('REST model info already exists')
    rest_model_info_dict[info.rest_name] = info
    
rest_initialized = False

def get_default_rest_name(model):
    # TODO: Ideally should do something a bit smarter here.
    # Something like convert from camel-case class names to hyphenated names:
    # For example:
    #  MyTestClass => my-test-class
    #  MyURLClass => my-url-class
    #
    # This isn't super-important for now, since you can set it explicitly
    # with the nested Rest class.
    return model.__name__.lower()

def initialize_rest():
    global rest_initialized
    if rest_initialized:
        return
    
    from django.db.models import get_models
    for model in get_models():
                
        # If the model class has a nested class named 'Rest' then that means
        # the model should be exposed in the REST API.
        if hasattr(model, 'Rest'):
            # By default the REST API uses the lower-case-converted name
            # of the model class as the name in the REST URL, but this can
            # be overridden by defining the 'NAME' attribute in the Rest class.
            if hasattr(model.Rest, 'NAME'):
                rest_name = model.Rest.NAME
            else:
                rest_name = get_default_rest_name(model)

            if model._meta.proxy:
                # This is a proxy class, drop through to the real one
                base_model = model._meta.proxy_for_model
            else:
                base_model = model
            
            # OK, we have the basic REST info, so we can create the info class
            rest_model_info = RestModelInfo(rest_name, base_model)
            
            # Check if there are any private or renamed fields
            if hasattr(model.Rest, 'FIELD_INFO'):
                for field_info in model.Rest.FIELD_INFO:
                    field_name = field_info['name']
                    rest_field_info = rest_model_info.get_field_info(field_name)
                    # Check if field exists in models - don't allow field only here in FIELD_INFO)
                    if not rest_field_info:
                        # LOOK! This field only exists in FIELD_INFO - skip
                        print "ERROR: %s for %s only in FIELD_INFO" % (field_name, rest_name)
                        continue
                    
                    if field_info.get('private', False):
                        rest_model_info.hide_field(field_name)
                    else:
                        rest_name = field_info.get('rest_name')
                        if rest_name:
                            rest_model_info.set_field_info(field_name, rest_name, rest_field_info.django_field_info)
            
            # Finished setting it up, so now add it to the list
            add_rest_model_info(rest_model_info)
    
    rest_initialized = True

initialize_rest()

@safe_rest_view
def do_model_list(request):
    """
    This returns the list of models available in the REST API.
    """
    
    json_model_list = []
    for model_name in rest_model_info_dict.keys():
        json_model_info = {}
        json_model_info["name"] = model_name
        json_model_info["url_path"] = "rest/v1/model/" + model_name + "/"
        json_model_list.append(json_model_info)

    json_data = simplejson.dumps(json_model_list)
    return HttpResponse(json_data, JSON_CONTENT_TYPE)

@safe_rest_view
def do_realtimestats(request, stattype, dpid):
    """
    This returns realtime statistics (flows, ports, table, aggregate,
    desc, ...)  for a dpid by calling the localhost sdnplatform
    """
    #raise RestInvalidMethodException()
    if request.method != 'GET':
        raise RestInvalidMethodException()
    #url = controller_url('core', 'switch', dpid, stattype, 'json')
    if stattype == 'group':
        stattype = 'groupStats'
    if stattype == 'groupdesc':
        stattype = 'groupDesc'
    url = "http://localhost:8080/wm/floodlight/core/switch/%s/%s/json" % (dpid, stattype)
    #url ="http://localhost:8080/wm/floodlight/core/switch/00:00:00:00:00:00:00:01/flow/json"
    return get_sdnplatform_response(url)

@safe_rest_view
def do_sdnplatform_realtimestats(request, stattype, dpid=None, portid=None):
    """
    This returns realtime statistics from sdnplatform
    """
    if request.method != 'GET':
        raise RestInvalidMethodException()
    if dpid == None:
        url = controller_url('core', 'counter', stattype, 'json')
    elif portid == None:
        url = controller_url('core', 'counter', dpid, stattype, 'json')
    else:
        url = controller_url('core', 'counter', dpid, portid, stattype, 'json')
    return get_sdnplatform_response(url)

@safe_rest_view
def do_topology_tunnel_verify(request, srcdpid=None, dstdpid=None):
    """
    This initiates a liveness detection of tunnels.
    """
    if request.method != 'GET':
        raise RestInvalidMethodException()

    urlstring = srcdpid + '/' + dstdpid
    url = controller_url('topology/tunnelverify', urlstring, 'json')

    response_text = urllib2.urlopen(url).read()
    time.sleep(4)
    return do_topology_tunnel_status(request, srcdpid, dstdpid)

@safe_rest_view
def do_topology_tunnel_status(request, srcdpid='all', dstdpid='all'):
    """
    This returns the list of tunnels that have failed over the last observation interval.
    """
    if request.method != 'GET':
        raise RestInvalidMethodException()

    urlstring = srcdpid + '/' + dstdpid
    url = controller_url('topology/tunnelstatus', urlstring, 'json')
    response_text = urllib2.urlopen(url).read()
    return HttpResponse(response_text, JSON_CONTENT_TYPE)

@safe_rest_view
def do_sdnplatform_realtimestatus(request, category=None, subcategory=None, srcdpid=None, dstdpid = None):
    """
    This returns realtime status of sdnplatform
    """

    if request.method != 'GET':
        raise RestInvalidMethodException()

    response_text = None
    url = None
    if category == 'network':
        if subcategory == 'cluster':
            url = controller_url('topology', 'switchclusters', 'json')
        if subcategory == 'externalports':
            url = controller_url('topology', 'externalports', 'json')
        if subcategory == 'tunnelverify':
            urlstring = subcategory+ '/' + srcdpid + '/' + dstdpid
            url = controller_url('topology', urlstring, 'json')
        if subcategory == 'tunnelstatus':
            url = controller_url('topology', 'tunnelstatus', 'json')

    if url:
        response_text = urllib2.urlopen(url).read()
    return HttpResponse(response_text, JSON_CONTENT_TYPE)

@safe_rest_view
def do_sdnplatform_realtimetest(http_request, category=None, subcategory=None):
    """
    This does a realtime test by sending an "explain packet" as packet in 
    and collecting the operations performed on the packet
    """

    if http_request.method != 'PUT':
        raise RestInvalidMethodException()

    response_text = None
    url = None
    if category == 'network':
        if subcategory == 'explain-packet':
            # set up the sdnplatform URL for explain packet (at internal port 8080
            url = controller_url('vns', 'explain-packet', 'json')
            post_data = http_request.raw_post_data
            request = urllib2.Request(url, post_data)
            request.add_header('Content-Type', 'application/json')
            response = urllib2.urlopen(request)
            response_text = response.read()
        elif subcategory == 'path':
            post_data = json.loads(http_request.raw_post_data)
            url = controller_url('topology', 'route',
                                 post_data['src-switch'],
                                 str(post_data['src-switch-port']),
                                 post_data['dst-switch'],
                                 str(post_data['dst-switch-port']),
                                 'json')

            return get_sdnplatform_response(url)

    return HttpResponse(response_text, JSON_CONTENT_TYPE)

@safe_rest_view
def do_sdnplatform_performance_monitor(http_request, category=None,
                    subcategory=None, type='all'):
    """
    This API returns performance related information from the sdnplatform and
    sdnplatform components
    """

    if http_request.method != 'GET':
        raise RestInvalidMethodException()

    response_text = None
    url = None
    if category == 'performance-monitor':
        # set up the sdnplatform URL for explain packet (at internal port 8080
        url = controller_url('performance', type, 'json')
        request = urllib2.Request(url)
        response = urllib2.urlopen(request)
        response_text = response.read()
    return HttpResponse(response_text, JSON_CONTENT_TYPE)

@safe_rest_view
def do_sdnplatform_internal_debugs(http_request, category=None, subcategory=None,
                              query='all', component='device-manager'):
    """
    This API returns debugging related information from the sdnplatform and
    sdnplatform components
    """

    if http_request.method != 'GET':
        raise RestInvalidMethodException()

    response_text = None
    url = None
    if category == 'internal-debugs':
        # set up the sdnplatform URL for explain packet (at internal port 8080
        url = controller_url('vns', 'internal-debugs', component, query, 'json')
        request = urllib2.Request(url)
        response = urllib2.urlopen(request)
        response_text = response.read()
    return HttpResponse(response_text, JSON_CONTENT_TYPE)

@safe_rest_view
def do_sdnplatform_event_history(http_request, category=None, subcategory=None,
                              evHistName='all', count='100'):
    """
    This API returns real-time event-history information from the sdnplatform and
    sdnplatform components
    """

    if http_request.method != 'GET':
        raise RestInvalidMethodException()

    response_text = None
    url = None
    if category == 'event-history':
        # set up the sdnplatform URL for explain packet (at internal port 8080
        url = controller_url('core', 'event-history', evHistName, count, 'json')
        request  = urllib2.Request(url)
        response = urllib2.urlopen(request)
        response_text = response.read()
    return HttpResponse(response_text, JSON_CONTENT_TYPE)

@safe_rest_view
def do_flow_cache(http_request, category=None, subcategory=None,
                          applName='None', applInstName='all', queryType='all'):
    """
    This API returns real-time event-history information from the sdnplatform and
    sdnplatform components
    """

    if http_request.method != 'GET':
        raise RestInvalidMethodException()

    response_text = None
    url = None
    if category == 'flow-cache':
        # set up the sdnplatform URL for explain packet (at internal port 8080
        url = controller_url('vns', 'flow-cache', applName, applInstName, queryType, 'json')
        request  = urllib2.Request(url)
        response = urllib2.urlopen(request)
        response_text = response.read()
    return HttpResponse(response_text, JSON_CONTENT_TYPE)


@safe_rest_view
def do_vns_realtimestats_flow(http_request, category=None, vnsName="all"):
    """
    This gets realtime flows for one or more vnses
    """

    if http_request.method != 'GET':
        raise RestInvalidMethodException()

    # set up the sdnplatform URL for per-vns flow (at internal port 8080
    url = controller_url('vns', 'flow', vnsName, 'json')
    return get_sdnplatform_response(url)

@safe_rest_view
def do_sdnplatform_counter_categories(request, stattype, layer, dpid=None, portid=None):
    """
    This returns counter categories from sdnplatform
    """
    if request.method != 'GET':
        raise RestInvalidMethodException()
    if dpid == None:
        url = controller_url('core', 'counter', 'categories', stattype, layer, 'json')
    elif portid == None:
        url = controller_url('core', 'counter', 'categories', dpid, stattype, layer, 'json')
    else:
        url = controller_url('core', 'counter', 'categories', dpid, portid, stattype, layer, 'json')

    return get_sdnplatform_response(url)

@safe_rest_view
@csrf_exempt
def do_packettrace(request):
    """
    This sets a packet trace in sdnplatform.
    period: 
        . >0 starts a trace session with the period
        . =0 starts a trace session with no timeout
        . <0 ends an ongoing session

    The request method has to be POST since each request gets an unique sessionID
    """
    SESSIONID = 'sessionId'
    sessionId = ""
    filter = ""
    if request.method != 'POST':
        raise RestInvalidMethodException()

    url = 'http://localhost:8080/wm/vns/packettrace/json'
    request = urllib2.Request(url, request.raw_post_data, {'Content-Type':'application/json'})
    try:
        response = urllib2.urlopen(request)
        response_text = response.read()
    except Exception, e:
        # SDNPlatform may not be running, but we don't want that to be a fatal
        # error, so we just ignore the exception in that case.
        pass

    #response_data = json.loads(response_text) 
    #if SESSIONID in response_data:
    #    sessionId = response_data[SESSIONID]
    #response_text = {SESSIONID:sessionId}

    return HttpResponse(response_text, mimetype=JSON_CONTENT_TYPE)

@safe_rest_view
def do_controller_stats(request, stattype):
    """
    This returns controller-level statistics/info from sdnplatform
    """
    if request.method != 'GET':
        raise RestInvalidMethodException()
    url = 'http://127.0.0.1:8080/wm/core/controller/%s/json' % stattype
    return get_sdnplatform_response(url)

@safe_rest_view
def do_controller_storage_table_list(request):
    """
    This returns controller-level storage table list
    """
    if request.method != 'GET':
        raise RestInvalidMethodException()
    url = 'http://127.0.0.1:8080/wm/core/storage/tables/json'
    return get_sdnplatform_response(url)

@safe_rest_view
def do_device(request):
    if onos == 0:
        return get_sdnplatform_query(request, "device")
    else:
        url = controller_url("onos", "topology", "hosts")
        if request.META['QUERY_STRING']:
            url += '?' + request.META['QUERY_STRING']
        return get_sdnplatform_response(url)        

@safe_rest_view
def do_switches(request):
    if onos == 0:
        url = controller_url("core", "controller", "switches", "json")
    else:
        url = controller_url("onos", "topology", "switches")
    if request.META['QUERY_STRING']:
        url += '?' + request.META['QUERY_STRING']
    return get_sdnplatform_response(url)        

@safe_rest_view
def do_mastership(request):
    url = controller_url("onos", "registry", "switches" ,"json")
    #url = "http://127.0.0.1:8080/wm/onos/registry/switches/json"
    if request.META['QUERY_STRING']:
        url += '?' + request.META['QUERY_STRING']
    return get_sdnplatform_response(url)

@safe_rest_view
def do_controller(request):
    url = controller_url("onos", "registry", "controllers" ,"json")
    #url = "http://127.0.0.1:8080/wm/onos/registry/switches/json"
    if request.META['QUERY_STRING']:
        url += '?' + request.META['QUERY_STRING']
    return get_sdnplatform_response(url) 
#'''

@safe_rest_view
def do_links(request):
    if onos == 0:
        url = controller_url("topology", "links", "json")
    else:
        url = controller_url("onos", "topology", "links")
    if request.META['QUERY_STRING']:
        url += '?' + request.META['QUERY_STRING']
    return get_sdnplatform_response(url)        

@safe_rest_view
def do_vns_device_interface(request):
    return get_sdnplatform_query(request, "vns/device-interface")

@safe_rest_view
def do_vns_interface(request):
    return get_sdnplatform_query(request, "vns/interface")

@safe_rest_view
def do_vns(request):
    return get_sdnplatform_query(request, "vns")

@safe_rest_view
def do_system_version(request):
    if request.method != 'GET':
        raise RestInvalidMethodException()
    version = get_system_version_string()
    response_text = simplejson.dumps([{ 'controller' : version }])
    return HttpResponse(response_text, JSON_CONTENT_TYPE)

available_log_files = {
    'syslog'           : '/var/log/syslog',
    'sdnplatform'       : '/opt/sdnplatform/sdnplatform/log/sdnplatform.log',
    'console-access'   : '/opt/sdnplatform/con/log/access.log',
    'cassandra'        : '/opt/sdnplatform/db/log/system.log',
    'authlog'          : '/var/log/auth.log',
    'pre-start'        : '/tmp/pre-start',
    'post-start'       : '/tmp/post-start',
    # 'ftp'              : '/var/log/ftp.log',
}

available_log_commands = {
    'dmesg'     : 'dmesg',
    'process'   : 'ps lax'
}

@safe_rest_view
def do_system_log_list(request):
    if request.method != 'GET':
        raise RestInvalidMethodException()
    existing_logs = []
    for (log_name, log_path) in available_log_files.items():
        try:
            log_file = open(log_path, 'r')
            existing_logs.append({ 'log' : log_name })
            log_file.close()
        except Exception, e:
            pass

    print '??'
    for log_name in available_log_commands.keys():
        print 'ADD', log_name
        existing_logs.append({ 'log' : log_name })
    response_text = simplejson.dumps(existing_logs)
    return HttpResponse(response_text, JSON_CONTENT_TYPE)


def generate_subprocess_output(cmd):

    process = subprocess.Popen(cmd, shell=True,
                                   stdout=subprocess.PIPE,
                                   stderr=subprocess.STDOUT,
                                   bufsize=1)
    while True:
        line = process.stdout.readline()
        if line != None and line != "":
            yield line
        else:
            break


@safe_rest_view
def do_system_log(request, log_name):
    if request.method != 'GET':
        raise RestInvalidMethodException()
    print 'do system log', log_name

    # manage command ouput differently
    if log_name in available_log_commands:
        cmd = available_log_commands[log_name]
        print 'DOING COMMAND', cmd

        return HttpResponse(generate_subprocess_output(cmd),
                            TEXT_PLAIN_CONTENT_TYPE)
        return

    log_path = available_log_files.get(log_name)
    if log_name == None:
        raise RestInvalidLog('No such log: %s' % log_name)
    
    try:
        log_file = open(log_path, 'r')
    except Exception,e:
        raise RestInvalidLog('Log does not exist: %s' % log_name)
        
    # use a generator so that the complete log is not ever held in memory
    def response(log_name, file):
        for line in file:
            yield line
        file.close()

    return HttpResponse(response(log_name, log_file), TEXT_PLAIN_CONTENT_TYPE)


@safe_rest_view
def do_system_uptime(request):
    if request.method != 'GET':
        raise RestInvalidMethodException()
    url = controller_url('core', 'system', 'uptime', 'json')
    return get_sdnplatform_response(url)        


def _collect_system_interfaces(lo = False):
    from netifaces import interfaces, ifaddresses, AF_INET, AF_LINK
    result = []
    for iface in interfaces():
        if iface.startswith('lo') and not lo:
            continue # ignore loopback
        addrs = ifaddresses(iface)
        if AF_INET in addrs:
            for addr in ifaddresses(iface)[AF_INET]:
                result.append({'name'      : iface,
                               'addr'      : addr.get('addr', ''),
                               'netmask'   : addr.get('netmask', ''),
                               'broadcast' : addr.get('broadcast', ''),
                               'peer'      : addr.get('peer', '')})
    return result


def do_system_inet4_interfaces(request):
    if request.method != 'GET':
        raise RestInvalidMethodException()
    response_text = simplejson.dumps(_collect_system_interfaces(lo = True))
    return HttpResponse(response_text, JSON_CONTENT_TYPE)


@safe_rest_view
def do_system_time_zone_strings(request, list_type):
    import pytz
    if list_type == 'common':
        string_list = pytz.common_timezones
    elif list_type == "all":
        string_list = pytz.all_timezones
    else:
        raise RestResourceNotFoundException(request.path)
    
    response_text = simplejson.dumps(string_list)
    
    return HttpResponse(response_text, JSON_CONTENT_TYPE)

@safe_rest_view
def do_check_config(request):
    config_check_state()
    return get_successful_response('checked config')

@safe_rest_view
def do_local_controller_id(request):
    if request.method == 'GET':
        controller_id = get_local_controller_id()
        if not controller_id:
            raise Exception("Unspecified local controller id")
        response_text = simplejson.dumps({'id': controller_id})
    elif request.method == 'PUT':
        put_data = json.loads(request.raw_post_data)
        controller_id = put_data.get('id')
        _result = exec_os_wrapper("ControllerId", 'set', [controller_id])
        response_text = get_successful_response_data('updated')
    else:
        raise RestInvalidMethodException()
    
    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
    
    return response

@safe_rest_view
def do_ha_failback(request):
    if request.method != 'PUT':
        raise RestInvalidMethodException()
    _result = exec_os_wrapper("HAFailback", 'set', [])
    response_text = get_successful_response_data('forced failback')
    response = HttpResponse(response_text, JSON_CONTENT_TYPE)
    return response

def delete_ha_firewall_rules(ip):
    rules = FirewallRule.objects.filter(action='allow', src_ip=ip)
    rules.filter(port=80).delete()
    rules.filter(proto='tcp', port=7000).delete()
    rules.filter(proto='vrrp').delete()

def cascade_delete_controller_node(controller_id):
    ControllerAlias.objects.filter(controller=controller_id).delete()
    ControllerDomainNameServer.objects.filter(controller=controller_id).delete()
    for iface in ControllerInterface.objects.filter(controller=controller_id):
        FirewallRule.objects.filter(interface=iface.id).delete()
    ControllerInterface.objects.filter(controller=controller_id).delete()
    Controller.objects.filter(id=controller_id).delete()

# FIXME: this assume a single-interface design and will look for the IP on eth0
#        need to fix this when we have a proper multi-interface design
def get_controller_node_ip(controller_id):
    node_ip = ''
    iface = ControllerInterface.objects.filter(controller=controller_id, type='Ethernet', number=0)
    if iface:
        node_ip = iface[0].discovered_ip
    return node_ip

# This method is "external" facing
# It is designed to be called by CLI or other REST clients
# This should only run on the master node, where decommissioning of a remote node is initiated
@safe_rest_view
def do_decommission(request):
    if request.method != 'PUT':
        raise RestInvalidMethodException()
    data = simplejson.loads(request.raw_post_data)
    node_id = data['id']

    # Disallow self-decommissioning
    local_id = get_local_controller_id()
    if local_id == node_id:
        raise RestDecommissionException("Decommissioning of the master node is not allowed. " + \
                                        "Please perform a failover first.")

    try :
        controller = Controller.objects.get(id=node_id)
    except Controller.DoesNotExist:
        raise RestDecommissionException("No controller found")

    node_ip = get_controller_node_ip(node_id)

    # Case 1: controller node has IP
    if node_ip:
        result = exec_os_wrapper("Decommission", 'set', [node_ip])
        output = result['out'].strip()
        if result['out'].strip().endswith('is already decommissioned'):
            delete_ha_firewall_rules(node_ip)
            cascade_delete_controller_node(node_id)

    # Case 2: controller node has NO IP
    else:
        output = '%s is already decommissioned' % node_id
        cascade_delete_controller_node(node_id)

    jsondict = {}
    jsondict['status'] = "OK"
    jsondict['description'] = output
    return HttpResponse(simplejson.dumps(jsondict), JSON_CONTENT_TYPE)

# This method is "internal" facing
# It is designed to be called only by sys/remove-node.sh
# This should only run on the node being decommissioned (slave)
@safe_rest_view
def do_decommission_internal(request):
    if request.method != 'PUT':
        raise RestInvalidMethodException()
    data = simplejson.loads(request.raw_post_data)
    node_ip = data['ip']
    exec_os_wrapper("DecommissionLocal", 'set', [node_ip])

    jsondict = {}
    jsondict['status'] = "OK"
    return HttpResponse(simplejson.dumps(jsondict), JSON_CONTENT_TYPE)

@safe_rest_view
def do_ha_provision(request):
    if request.method != 'PUT':
        raise RestInvalidMethodException()
    data = simplejson.loads(request.raw_post_data)
    node_ip = data['ip']
    
    try :
        ci = ControllerInterface.objects.get(ip=node_ip)
        id = ci.controller.id
        print 'got id', id
        try:
            a = ControllerAlias.objects.get(controller=id)
            alias = a.alias
        except:
            alias = '(no controller alias)'

        print 'alias:', alias
        raise RestProvisionException('ip address already in controller %s %s' %
                                     (id, alias))
        
    except ControllerInterface.DoesNotExist:
        id = uuid.uuid4().urn[9:]
        print "generated id = ", id
        c = Controller(id=id)
        try:
            c.save()
        except:
            # describe failure
            raise RestProvisionException('can\t save controller')
            pass
        print "save controller"
        ci = ControllerInterface(controller=c,
                                 ip=node_ip,
                                 discovered_ip=node_ip)
        try:
            ci.save()
        except:
            # describe failure
            raise RestProvisionException('can\t save controllar interfacer')

    for c in Controller.objects.all():
        if c.id != id:
            #if there are multiple interfaces, assume the
            # ethernet0 interface is for management purpose 
            # XXX this could be better.
            iface = ControllerInterface.objects.get(controller=c.id,
                                                    type='Ethernet',
                                                    number=0)
            ip = iface.ip
            fw = FirewallRule(interface=iface, action='allow',
                              src_ip=node_ip, port=80, proto='tcp')
            try:
                fw.save()
            except:
                # describe failure
                raise RestProvisionException('can\t save firewall rule from master')
                
            fw = FirewallRule(interface=ci, action='allow',
                              src_ip=ip, port=80, proto='tcp')
            try:
                fw.save()
            except:
                raise RestProvisionException('can\t save firewall from slave')
        

    response_text = get_successful_response_data(id)
    response = HttpResponse(response_text, JSON_CONTENT_TYPE)

    return response


def get_clustername():
    name = os.popen("grep cluster_name /opt/sdnplatform/db/conf/cassandra.yaml | awk  '{print $2}'").readline()
    # name may be '', perhaps this ought to None?
    return name


@safe_rest_view
def do_clustername(request):
    if request.method != 'GET':
        raise RestInvalidMethodException()
    response_text = simplejson.dumps([{ 'clustername' : get_clustername() }])
    return HttpResponse(response_text, JSON_CONTENT_TYPE)
    
    
@safe_rest_view
def do_local_ha_role(request):
    if request.method != 'GET':
        raise RestInvalidMethodException()

    url = controller_url('core', 'role', 'json')
    try:
        response_text = urllib2.urlopen(url, timeout=2).read()
        response = json.loads(response_text)
    except Exception:
        response = HttpResponse('{"role":"UNAVAILABLE"}', JSON_CONTENT_TYPE)
        return response
    # now determine our controller id
    controller_id = get_local_controller_id()

    # find all the interfaces
    ifs = ControllerInterface.objects.filter(controller=controller_id)

    for intf in ifs:
        firewall_id = '%s|%s|%s' % (controller_id, intf.type, intf.number)

        rules = FirewallRule.objects.filter(interface=firewall_id)
        for rule in rules:
            if rule.action == 'reject' and rule.proto == 'tcp' and rule.port == 6633:
                if response['role'] in {'MASTER', 'SLAVE'}:
                    response['role']+='-BLOCKED'

    response['clustername'] = get_clustername()
        
    return HttpResponse(simplejson.dumps(response), JSON_CONTENT_TYPE)

@safe_rest_view
def do_system_clock(request, local=True):
    local_or_utc_str = 'local' if local else 'utc'
    if request.method == 'GET':
        result = exec_os_wrapper("DateTime", 'get', [local_or_utc_str])
    elif request.method == 'PUT':
        time_info = simplejson.loads(request.raw_post_data)
        dt = datetime(**time_info)
        new_date_time_string = dt.strftime('%Y:%m:%d:%H:%M:%S')
        result = exec_os_wrapper("DateTime", 'set', [local_or_utc_str, new_date_time_string])
    else:
        raise RestInvalidMethodException()

    if len(result) == 0:
        raise Exception('Error executing date command')
    
    # The DateTime OS wrapper only has a single command so the return
    # date/time is the first line of the first element of the out array
    values = result['out'].strip().split(':')
    date_time_info = {
        'year': int(values[0]),
        'month': int(values[1]),
        'day': int(values[2]),
        'hour': int(values[3]),
        'minute': int(values[4]),
        'second': int(values[5]),
        'tz': values[6]
    }
    response_text = simplejson.dumps(date_time_info)
    response = HttpResponse(response_text, JSON_CONTENT_TYPE)

    return response

@safe_rest_view
def do_instance(request, model_name,id=None):
    """
    This function handles both GET and PUT methods.
    
    For a GET request it returns a list of all of the instances of the
    model corresponding to the specified type that match the specified
    query parameters. If there are no query parameters then it returns
    a list of all of the instances of the specified type. The names of
    the query parameters can use the Django double underscore syntax
    for doing more complicated tests than just equality
    (e.g. mac__startswith=192.168).
    
    For a PUT request it can either update an existing instance or
    insert one or more new instances. If there are any query parameters
    then it assumes that its the update case and that the query
    parameters identify exactly one instance. If that's not the case
    then an error response is returned. For the update case any subset
    of the fields can be updated with the PUT data. The format of the
    PUT data is a JSON dictionary
    """
    
    # FIXME: Hack to remap 'localhost' id for the controller-node model
    # to the real ID for this controller
    if model_name == 'controller-node' and id == 'localhost':
        id = get_local_controller_id()
        
    # Lookup the model class associated with the specified name
    model_info = rest_model_info_dict.get(model_name)
    if not model_info:
        raise RestInvalidDataTypeException(model_name)
            
    # Set up the keyword argument dictionary we use to filter the QuerySet.
    filter_keyword_args = {}

    jsonp_prefix = None
    nolist = False
    order_by = None
    
    # Now iterate over the query params and add further filter keyword arguments
    query_param_dict = request.GET
    for query_param_name, query_param_value in query_param_dict.items():
        add_query_param = False
        query_param_name = str(query_param_name)
        query_param_value = str(query_param_value)
        if query_param_name == 'callback': #switching to match up with jquery getJSON call naming convention.
            jsonp_prefix = query_param_value
        elif query_param_name == 'nolist':
            if query_param_value not in ('False', 'false', '0', ''):
                nolist = True
        elif query_param_name == 'orderby':
            order_by = query_param_value.split(',')
            for i in range(len(order_by)):
                name = order_by[i]
                if name.startswith('-'):
                    descending = True
                    name = name[1:]
                else:
                    descending = False
                field_info = model_info.rest_name_dict.get(name)
                if not field_info:
                    raise RestInvalidOrderByException(name)
                name = field_info.name
                if descending:
                    name = '-' + name
                order_by[i] = name
        elif query_param_name in model_info.rest_name_dict:
            field_info = model_info.rest_name_dict.get(query_param_name)
            # For booleans, translate True/False strings into 0/1.
            if field_info and type(field_info.django_field_info) == BooleanField:
                if query_param_value.lower() == 'false':
                    query_param_value = 0
                elif query_param_value.lower() == 'true':
                    query_param_value = 1
            query_param_name = field_info.name
            if model_name == 'controller-node' and \
              query_param_name == 'id' and query_param_value == 'localhost':
                query_param_value = get_local_controller_id()
            if model_name in 'controller-interface' and \
              query_param_name == 'controller' and \
              query_param_value == 'localhost':
                query_param_value = get_local_controller_id()
            add_query_param = True
        else:
            double_underscore_start = query_param_name.find("__")
            if double_underscore_start >= 0:
                rest_name = query_param_name[:double_underscore_start]
                field_info = model_info.rest_name_dict.get(rest_name)
                if field_info:
                    operation = query_param_name[double_underscore_start:]
                    query_param_name = field_info.name
                    if type(field_info.django_field_info) == ForeignKey:
                        query_param_name = query_param_name + '__' + field_info.django_field_info.rel.field_name
                    # Substitute in the model field name for the (possible renamed) rest name
                    query_param_name += operation
                    add_query_param = True
        if add_query_param:
            filter_keyword_args[query_param_name] = query_param_value

    if id != None:
        if len(filter_keyword_args) > 0:
            raise RestInvalidFilterParameterException(filter_keyword_args.keys()[0])
        try:
            get_args = {model_info.primary_key:id}
            instance = model_info.model_class.objects.get(**get_args)
            instance_list = (instance,)
            nolist = True
        except model_info.model_class.DoesNotExist,e:
            raise RestResourceNotFoundException(request.path)
        except model_info.model_class.MultipleObjectsReturned, exc:
            # traceback.print_exc()
            raise RestInternalException(exc)
    elif (request.method != 'PUT') or (len(filter_keyword_args) > 0):
        # Get the QuerySet based on the keyword arguments we constructed
        instance_list = model_info.model_class.objects.filter(**filter_keyword_args)
        if order_by:
            instance_list = instance_list.order_by(*order_by)
    else:
        # We're inserting new objects, so there's no need to do a query
        instance_list = None
        
    response_content_type = JSON_CONTENT_TYPE
    
    if request.method == 'GET':
        json_response_data = []
        for instance in instance_list:
            json_instance = {}
            for field_info in model_info.field_name_dict.values():
                # Made some minor edits to deal with a) fields that are empty and b) fields that are not strings -Kyle
                # Changed this to only do an explicit string conversion if it's a unicode string.
                # The controller is expecting to get the unstringified value (e.g. for boolean values)
                # Not sure if this will break things in the UI, but we'll need to resolve how
                # we want to handle this. Also, how do we want to handle unicode strings? -- robv
                field_name = field_info.name
                if type(field_info.django_field_info) == ForeignKey:
                    field_name += '_id'
                value = instance.__dict__.get(field_name)
                if value != None:
                    if field_info.json_serialize:
                        value = str(value)
                    json_instance[field_info.rest_name] = value
            json_response_data.append(json_instance)
        
        # If the nolist query param was enabled then check to make sure
        # that there was only a single instance in the response list and,
        # if so, unpack it from the list
        if nolist:
            if len(json_response_data) != 1:
                raise RestNoListResultException()
            json_response_data = json_response_data[0]
        
        # Convert to json
        response_data = simplejson.dumps(json_response_data)
        
        # If the jsonp query parameter was specified, wrap the data with
        # the jsonp prefix
        if jsonp_prefix:
            response_data = jsonp_prefix + '(' + response_data + ')'
            # We don't really know what the content type is here, but it's typically javascript
            response_content_type = TEXT_JAVASCRIPT_CONTENT_TYPE
    elif request.method == 'PUT':
        response_data = get_successful_response_data('saved')
        response_content_type = JSON_CONTENT_TYPE
        
        begin_batch_notification()
        json_object = simplejson.loads(request.raw_post_data)
        if instance_list is not None:

            # don't allow the ip address of the first interface to
            # be updated once it is set.  This really applies to
            # the interface cassandra uses to sync the db.
            if model_name == 'controller-interface':
                for instance in instance_list:
                    if instance.number == 0 and instance.ip != '':
                        if 'ip' in json_object and json_object['ip'] != instance.ip:
                            raise RestModelException("In this version, ip-address of primary interface can't be updated after initial configuration")

            # In this case the URL includes query parameter(s) which we assume
            # narrow the request to the instances of the model to be updated
            # updated with the PUT data. So we're updating existing instances
            
            # If it's a list with one element then extract the single element
            if (type(json_object) == list) and (len(json_object) == 1):
                json_object = json_object[0]
                
            # We're expecting a dictionary where the keys match the model field names
            # If the data isn't a dictionary then return an error
            if type(json_object) != dict:
                raise RestInvalidPutDataException() # TODO: Should return something different here
            
            # Set the fields in the model instance with the data from the dictionary
            for instance in instance_list:
                for rest_name, value in json_object.items():
                    if not rest_name in model_info.rest_name_dict:
                        raise RestModelException("Model '%s' has no field '%s'" % 
                                                 (model_name, rest_name))
                    field_info = model_info.rest_name_dict[rest_name]
                    field_name = str(field_info.name)   # FIXME: Do we need the str cast?
                    if type(field_info.django_field_info) == ForeignKey:
                        field_name += '_id'
                    # TODO: Does Django still not like unicode strings here?
                    if type(value) == unicode:
                        value = str(value)
                    instance.__dict__[field_name] = value
                # Save the updated model instance
                try:
                    instance.full_clean()
                    instance.save()
                except ValidationError, err:
                    handle_validation_error(model_info, err)
                    #raise RestValidationException(err)
                except Exception, exc:
                    raise RestSaveException(exc)
        else:
            # In this case no query parameters or id were specified so we're inserting new
            # instances into the database. The PUT data can be either a list of new
            # items to add (i.e. top level json object is a list) or else a single
            # new element (i.e. top-level json object is a dict).
            #print "creating object(s)"

            # To simplify the logic below we turn the single object case into a list
            if type(json_object) != list:
                json_object = [json_object]
            
            # Create new model instances for all of the items in the list
            for instance_data_dict in json_object:
                # We expect the data to be a dictionary keyed by the field names
                # in the model. If it's not a dict return an error
                if type(instance_data_dict) != dict:
                    raise RestInvalidPutDataException()
                
                converted_dict = {}
                
                # Now add the fields specified in the PUT data
                for rest_name, value in instance_data_dict.items():

                    #print "  processing " + str(name) + " " + str(value)

                    if not rest_name in model_info.rest_name_dict:
                        raise RestModelException("Model '%s' has no field '%s'" % 
                                                 (model_name, rest_name))
                    field_info = model_info.rest_name_dict[rest_name]
                    # simplejson uses unicode strings when it loads the objects which
                    # Django doesn't like that, so we convert these to ASCII strings
                    if type(rest_name) == unicode:
                        rest_name = str(rest_name)
                    if type(value) == unicode:
                        value = str(value)
                    field_name = field_info.name
                    # FIXME: Hack to remap localhost controller node id alias to the actual
                    # ID for the controller node. We shouldn't be doing this here (this code
                    # shouldn't have anything about specific models), but it's the easiest
                    # way to handle it for now and this code is likely going away sometime
                    # pretty soon (written in May, 2012, let's see how long "pretty soon"
                    # is :-) )
                    if model_name == 'controller-node' and field_name == 'id' and value == 'localhost':
                        value = get_local_controller_id()
                    if type(field_info.django_field_info) == ForeignKey:
                        field_name += '_id'
                    converted_dict[field_name] = value
                
                try:
                    instance = model_info.model_class(**converted_dict)
                    instance.full_clean()
                    instance.save()
                except ValidationError, err:
                    handle_validation_error(model_info, err)
                    #raise RestValidationException(err)
                except Exception, e:
                    # traceback.print_exc()
                    raise RestSaveException(e)
                
        end_batch_notification()
    elif request.method == 'DELETE':
        begin_batch_notification()
        for instance in instance_list:
            try:
                instance.delete()
            except ValidationError, err:
                handle_validation_error(model_info, err)
            except Exception, e:
                raise RestException(e)
        end_batch_notification()
        response_data = "deleted"
        response_content_type = 'text/plain'
    else:
        raise RestInvalidMethodException()
    
    return HttpResponse(response_data, response_content_type)

def synthetic_controller_interface(model_name, query_param_dict, json_response_data):
    # ---
    if model_name == 'controller-interface':
        # For controller-interfaces, when an ip address (netmask too)
        # is left unconfigured, then it may be possible to associate
        # ifconfig details with the interface.
        #
        # Since controller-interfaces has no mechanism to associate 
        # specific ifconfig interfaces with rows, it's only possible to
        # associate ip's when a single unconfigured ip address exists,
        # using a process of elimination.  For all ip address in the
        # ifconfig output, all statically configured controller-interface
        # items are removed.  If only one result is left, and only
        # one controller-interface has an unconfigured ip address
        # (either a dhcp acquired address, or a static address where
        # the ip address is uncofigured), the ifconfig ip address
        # is very-likely to be the one associated with the 
        # controller-interface row.

        # Check the list of values to see if any are configured as dhcp
        dhcp_count = 0
        unconfigured_static_ip = 0
        this_host = get_local_controller_id()

        for entry in json_response_data:
            if 'mode' in entry and entry['mode'] == 'dhcp' and \
               'controller' in entry and entry['controller'] == this_host:
                    dhcp_count += 1
            if 'mode' in entry and entry['mode'] == 'static' and \
               'ip' in entry and entry['ip'] == '':
                    unconfigured_static_ip += 1
        if dhcp_count + unconfigured_static_ip != 1:
            for entry in json_response_data:
                entry['found-ip']        = entry['ip']
            return

        need_controller_query = False
        # determine whether the complete list of interfaces needs
        # to be collected to associate the dhcp address.
        for query_param_name, query_param_value in query_param_dict.items():
            if query_param_name != 'controller':
                need_controller_query = True
            if query_param_name == 'controller' and \
               query_param_value != this_host:
                need_controller_query = True

        if need_controller_query == False:
            model_interfaces = [x for x in json_response_data
                                if 'controller' in x and x['controller'] == this_host]
        else:
            # print 'need to collect all interfaces'
            filter_keyword_args = {'controller' : this_host}
            model_info = rest_model_info_dict.get(model_name)
            instance_list = model_info.model_class.objects.filter(**filter_keyword_args)
            response_data = []
            for instance in instance_list:
                data = {}
                for field_info in model_info.field_name_dict.values():
                    field_name = field_info.name
                    if type(field_info.django_field_info) == ForeignKey:
                        field_name += '_id'
                    value = instance.__dict__.get(field_name)
                    if value != None:
                        if field_info.json_serialize:
                            value = str(value)
                        data[field_info.rest_name] = value
                response_data.append(data)
            model_interfaces = response_data

        # Recompute the number of dhcp configured interfaces,
        # model_interfaces is the collection of interface for 'this_host'
        dhcp_count = 0
        unconfigured_static_ip = 0
        for ifs in model_interfaces:
            if 'mode' in ifs and ifs['mode'] == 'dhcp':
                dhcp_count += 1
            if 'mode' in ifs and ifs['mode'] == 'static' and \
               'ip' in ifs and ifs['ip'] == '':
                    unconfigured_static_ip += 1

        if dhcp_count + unconfigured_static_ip != 1:
            # print "Sorry, %s dhcp + %s unconfigured static interfaces on %s" % \
                  # (dhcp_count, unconfigured_static_ip, this_host)
            # copy over static ip's
            for entry in json_response_data:
                entry['found-ip']        = entry['ip']
            return

        # collect current details for all the network interfaces
        inet4_ifs = _collect_system_interfaces()

        # iterate over the model_interfaces's interfaces, and 
        # remove ip addresses from inet4_ifs which are static, and
        # have the correct static value.

        report_static = False
        match_id = ''

        for ifs in model_interfaces:
            if 'mode' in ifs and ifs['mode'] == 'static':
                if 'ip' in ifs and ifs['ip'] == '':
                    # print "Unconfigured static ip for %s", ifs['id']
                    match_id = ifs['id']
                if 'ip' in ifs and ifs['ip'] != '':
                    # find this address in the known addresses
                    remove_entry = -1
                    for index, inet4_if in enumerate(inet4_ifs):
                        if inet4_if['addr'] == ifs['ip']:
                            remove_entry = index
                            break
                    if remove_entry == -1:
                        # print "Static ip %s not found" % ifs['ip']
                        pass 
                    else:
                        del inet4_ifs[remove_entry]
            elif 'mode' in ifs and ifs['mode'] == 'dhcp':
                match_id = ifs['id']
            else:
                # ought to assert here, not_reached()
                pass

        # When only one entry is left in inet, its possible to do the assocation
        if len(inet4_ifs) != 1:
            # print "Incorrect number %s of inet4 interfaces left" % len(inet4_ifs)
            pass

        for entry in json_response_data:
            entry['found-ip']        = entry['ip']
            entry['found-netmask']   = entry['netmask']

            if entry['id'] == match_id:
                # make sure the address isn't set
                if entry['ip'] == '':
                    entry['found-ip']        = inet4_ifs[0]['addr']
                    entry['found-netmask']   = inet4_ifs[0]['netmask']
                    entry['found-broadcast'] = inet4_ifs[0]['broadcast']
                else:
                    # ought to assert here, not_reached()
                    pass

@safe_rest_view
def do_synthetic_instance(request, model_name, id=None):
    
    if request.method != 'GET':
        raise RestInvalidMethodException()

    # Lookup the model class associated with the specified name
    model_info = rest_model_info_dict.get(model_name)
    if not model_info:
        raise RestInvalidDataTypeException(model_name)
            
    # Set up the keyword argument dictionary we use to filter the QuerySet.
    filter_keyword_args = {}

    jsonp_prefix = None
    nolist = False
    order_by = None
    
    # Now iterate over the query params and add further filter keyword arguments
    query_param_dict = request.GET
    for query_param_name, query_param_value in query_param_dict.items():
        add_query_param = False
        query_param_name = str(query_param_name)
        query_param_value = str(query_param_value)
        if query_param_name == 'callback': #switching to match up with jquery getJSON call naming convention.
            jsonp_prefix = query_param_value
        elif query_param_name == 'nolist':
            if query_param_value not in ('False', 'false', '0', ''):
                nolist = True
        elif query_param_name == 'orderby':
            order_by = query_param_value.split(',')
            for i in range(len(order_by)):
                name = order_by[i]
                if name.startswith('-'):
                    descending = True
                    name = name[1:]
                else:
                    descending = False
                field_info = model_info.rest_name_dict.get(name)
                if not field_info:
                    raise RestInvalidOrderByException(name)
                name = field_info.name
                if descending:
                    name = '-' + name
                order_by[i] = name
        elif query_param_name in model_info.rest_name_dict:
            field_info = model_info.rest_name_dict.get(query_param_name)
            query_param_name = field_info.name
            add_query_param = True
        else:
            double_underscore_start = query_param_name.find("__")
            if double_underscore_start >= 0:
                rest_name = query_param_name[:double_underscore_start]
                field_info = model_info.rest_name_dict.get(rest_name)
                if field_info:
                    operation = query_param_name[double_underscore_start:]
                    query_param_name = field_info.name
                    if type(field_info.django_field_info) == ForeignKey:
                        query_param_name = query_param_name + '__' + field_info.django_field_info.rel.field_name
                    # Substitute in the model field name for the (possible renamed) rest name
                    query_param_name += operation
                    add_query_param = True
        if add_query_param:
            filter_keyword_args[query_param_name] = query_param_value

    if id != None:
        if len(filter_keyword_args) > 0:
            raise RestInvalidFilterParameterException(filter_keyword_args.keys()[0])
        try:
            get_args = {model_info.primary_key:id}
            instance = model_info.model_class.objects.get(**get_args)
            instance_list = (instance,)
            nolist = True
        except model_info.model_class.DoesNotExist,e:
            raise RestResourceNotFoundException(request.path)
        except model_info.model_class.MultipleObjectsReturned, exc:
            # traceback.print_exc()
            raise RestInternalException(exc)
    elif (request.method != 'PUT') or (len(filter_keyword_args) > 0):
        # Get the QuerySet based on the keyword arguments we constructed
        instance_list = model_info.model_class.objects.filter(**filter_keyword_args)
        if order_by:
            instance_list = instance_list.order_by(*order_by)
    else:
        # We're inserting new objects, so there's no need to do a query
        instance_list = None
        
    response_content_type = JSON_CONTENT_TYPE
    
    # Syntheric types only do requests --
    json_response_data = []
    for instance in instance_list:
        json_instance = {}
        for field_info in model_info.field_name_dict.values():
            # Made some minor edits to deal with a) fields that are empty and b) fields that are not strings -Kyle
            # Changed this to only do an explicit string conversion if it's a unicode string.
            # The controller is expecting to get the unstringified value (e.g. for boolean values)
            # Not sure if this will break things in the UI, but we'll need to resolve how
            # we want to handle this. Also, how do we want to handle unicode strings? -- robv
            field_name = field_info.name
            if type(field_info.django_field_info) == ForeignKey:
                field_name += '_id'
            value = instance.__dict__.get(field_name)
            if value != None:
                if field_info.json_serialize:
                    value = str(value)
                json_instance[field_info.rest_name] = value
        json_response_data.append(json_instance)
    
    # ---
    if model_name == 'controller-interface':
        synthetic_controller_interface(model_name, query_param_dict, json_response_data)

    # Convert to json
    response_data = simplejson.dumps(json_response_data)
    
    # If the nolist query param was enabled then check to make sure
    # that there was only a single instance in the response list and,
    # if so, unpack it from the list
    if nolist:
        if len(json_response_data) != 1:
            raise RestNoListResultException()
        json_response_data = json_response_data[0]
    
    # If the jsonp query parameter was specified, wrap the data with
    # the jsonp prefix
    if jsonp_prefix:
        response_data = jsonp_prefix + '(' + response_data + ')'
        # We don't really know what the content type is here, but it's typically javascript
        response_content_type = TEXT_JAVASCRIPT_CONTENT_TYPE

    return HttpResponse(response_data, response_content_type)

@safe_rest_view
def do_user_data_list(request):
    # Now iterate over the query params and add any valid filter keyword arguments
    filter_keyword_args = {}
    for query_param_name, query_param_value in request.GET.items():
        query_param_name = str(query_param_name)
        double_underscore_start = query_param_name.find("__")
        if double_underscore_start >= 0:
            attribute_name = query_param_name[:double_underscore_start]
        else:
            attribute_name = query_param_name
            
        # In the future, if we add support for things like mod_date, creation_date, etc.
        # which would be supported in query params, then they'd be added to this list/tuple.
        if attribute_name not in ('name',):
            raise RestInvalidFilterParameterException(query_param_name)
        filter_keyword_args[query_param_name] = query_param_value

    instance_list = UserData.objects.filter(**filter_keyword_args)
    
    if request.method == 'GET':
        user_data_info_list = []

        # FIXME: robv: It's incorrect to *always* add this to the user data,
        # because it means we're not respecting the filter query parameters.
        # To work completely correctly we'd need to duplicate a lot of logic
        # for processing the query parameters, which would be tedious.
        # Should talk to Mandeep about why it was done this way. Maybe we
        # should expose these special cases in a different URL/view.
        for fn in ['startup-config', 'upgrade-config']:
            try:
                sc = "%s/run/%s" % (sdncon.SDN_ROOT, fn)
                f = open(sc, 'r')
                f.close()
                t = time.strftime("%Y-%m-%d.%H:%M:%S",
                                  time.localtime(os.path.getmtime(sc)))
                instance_name = fn + '/timestamp=' + t + \
                                '/version=1/length=' + \
                                str(os.path.getsize(sc))
                url_path = 'rest/v1/data/' + instance_name + '/'
                            
                user_data_info = { 'name' : instance_name,
                                   'url_path' : url_path, }
                user_data_info_list.append(user_data_info)
            except:
                pass

        for instance in instance_list:
            user_data_info = {'name': instance.name,
                              'url_path': 'rest/v1/data/' + instance.name + '/'}
            user_data_info_list.append(user_data_info)
        
        response_data = simplejson.dumps(user_data_info_list)
    elif request.method == 'DELETE':
        instance_list.delete()
        response_data = {}
        response_data['status'] = 'success'
        response_data['message'] = 'user data deleted'
        response_data = simplejson.dumps(response_data)
        response_content_type = JSON_CONTENT_TYPE
    else:
        raise RestInvalidMethodException()
        
    return HttpResponse(response_data, JSON_CONTENT_TYPE)

@safe_rest_view
def do_user_data(request, name):
    query_param_dict = request.GET
    #
    # Manage startup-config/update-config differently
    if name.find('/') >= 0 and \
       name.split('/')[0] in ['startup-config', 'upgrade-config']:
        path = "%s/run/%s" % (sdncon.SDN_ROOT, name.split('/')[0])
        response_data = {}

        if request.method == 'GET':
            with open(path, 'r') as f:
                response_data = f.read()
            response_content_type = "text/plain"
        elif request.method == 'PUT':
            try:
                with open(path, 'w') as f:
                    f.write(request.raw_post_data)
                response_data['status'] = 'success'
                response_data['message'] = 'user data updated'
            except:
                response_data['status'] = 'failure'
                response_data['message'] = "can't write file"
            response_content_type = JSON_CONTENT_TYPE
            response_data = simplejson.dumps(response_data)
        elif request.method == 'DELETE':
            try:
                f = open(path, "r")
                f.close()
            except:
                raise RestResourceNotFoundException(request.path)

            try:
                os.remove(path)
                response_data['status'] = 'success'
                response_data['message'] = 'user data deleted'
            except:
                response_data['status'] = 'failure'
                response_data['message'] = "can't delete file"
            response_data = simplejson.dumps(response_data)
            response_content_type = JSON_CONTENT_TYPE
        else:
            raise RestInvalidMethodException()
            
        return HttpResponse(response_data, response_content_type)
            
    
    # Default values for optional query parameters
    #private = False
    binary = False
    
    for param_name, param_value in query_param_dict.items():
        if param_name == 'binary':
            if request.method != 'PUT':
                raise RestInvalidQueryParameterException(name)
            binary = param_value.lower() == 'true' or param_value == '1'
        #elif param_name == 'private':
        #    private = param_value
        else:
            raise RestInvalidQueryParameterException(param_name)
    
    # FIXME: Need HTTP basic/digest auth support for the following
    # code to work.
    #if private:
    #    user = request.user
    #else:
    #    user = None
    #if user != None and not user.is_authenticated():
    #    raise RestAuthenticationRequiredException()
    user = None
    
    # There's currently an issue with filtering on the user when using the
    # Cassandra database backend. Since we don't support private per-user
    # data right now, I'm just disabling filtering on the user and only
    # filter on the name
    #user_data_query_set = UserData.objects.filter(user=user, name=name)
    user_data_query_set = UserData.objects.filter(name=name)

    count = user_data_query_set.count()
    if count > 1:
        raise RestInternalException('Duplicate user data values for the same name')
    
    if request.method == 'GET':
        if count == 0:
            raise RestResourceNotFoundException(request.path)
        user_data = user_data_query_set[0]
        response_data = user_data.data
        if user_data.binary:
            response_data = base64.b64decode(response_data)
        response_content_type = user_data.content_type
    elif request.method == 'PUT':
        content_type = request.META['CONTENT_TYPE']
        if content_type == None:
            if binary:
                content_type = BINARY_DATA_CONTENT_TYPE
            else:
                content_type = JSON_CONTENT_TYPE
        response_data = {}
        if count == 1:
            response_data['status'] = 'success'
            response_data['message'] = 'user data updated'
            user_data = user_data_query_set[0]
        else:
            response_data['status'] = 'success'
            response_data['message'] = 'user data created'
            user_data = UserData(user=user,name=name)
        user_data.binary = binary
        user_data.content_type = content_type
        data = request.raw_post_data
        if binary:
            data = base64.b64encode(data)
        user_data.data = data
        user_data.save()
        response_data = simplejson.dumps(response_data)
        response_content_type = JSON_CONTENT_TYPE
    elif request.method == 'DELETE':
        if count == 0:
            raise RestResourceNotFoundException(request.path)
        user_data = user_data_query_set[0]
        user_data.delete()
        response_data = {}
        response_data['status'] = 'success'
        response_data['message'] = 'user data deleted'
        response_data = simplejson.dumps(response_data)
        response_content_type = JSON_CONTENT_TYPE
    else:
        raise RestInvalidMethodException()
   
    return HttpResponse(response_data, response_content_type)

@safe_rest_view
def do_sdnplatform_tunnel_manager(request, dpid=None):
    """
    This returns realtime statistics from sdnplatform
    """

    if request.method != 'GET':
        raise RestInvalidMethodException()
    if dpid == None:
        raise RestInvalidMethodException()

    print 'DPID', dpid
    if dpid == 'all':
        url = controller_url('vns', 'tunnel-manager', 'all', 'json')
    else:
        url = controller_url('vns', 'tunnel-manager', 'switch='+dpid, 'json')

    response_text = urllib2.urlopen(url).read()
    entries = simplejson.loads(response_text)

    if 'error' in entries and entries['error'] != None:
        RestInternalException(entries['error'])

    return HttpResponse(json.dumps(entries['tunnMap']), JSON_CONTENT_TYPE)

@safe_rest_view
def do_sdnplatform_controller_summary(request):
    """
    This returns summary statistics from sdnplatform modules
    """
    if request.method != 'GET':
        raise RestInvalidMethodException()

    url = controller_url('core', 'controller', 'summary', 'json')
    return get_sdnplatform_response(url)

def filter_queries(choice_list, param_dict):
    return dict([[x, param_dict[x]] for x in choice_list
                if x in param_dict and param_dict[x] != 'all'])

@safe_rest_view
def do_reload(request):
    """
    This calls an oswrapper that reloads the box.
    """
    if request.method != 'GET':
        raise RestInvalidMethodException()
    exec_os_wrapper("ReloadController", 'set', [])
    response_text = '{"status":"reloading"}'
    return HttpResponse(response_text, JSON_CONTENT_TYPE)

@safe_rest_view
def do_resetbsc(request):
    """
    This calls an oswrapper that resets the box.
    """
    if request.method != 'PUT':
        raise RestInvalidMethodException()
    exec_os_wrapper("ResetBsc", 'set', [])
    response_text = '{"status":"resetting"}'
    return HttpResponse(response_text, JSON_CONTENT_TYPE)

@safe_rest_view
def do_abort_upgrade(request):
    """
    This calls an oswrapper that reloads the box.
    """
    if request.method != 'PUT':
        raise RestInvalidMethodException()
    controller_id = get_local_controller_id()
    controller = Controller.objects.get(id=controller_id)
    if controller.status != 'Upgrading':
        raise RestUpgradeException("No Upgrade pending")
    exec_os_wrapper("AbortUpgrade", 'set', [])
    controller.status = 'Ready'
    controller.save()
    response_text = '{"status":"Ready"}'
    return HttpResponse(response_text, JSON_CONTENT_TYPE)

@safe_rest_view
def do_config_rollback(request):
    data = simplejson.loads(request.raw_post_data)
    path = data['path']
    print "Executing config rollback with config @", path
    
    if request.method != 'PUT':
        raise RestInvalidMethodException()
    exec_os_wrapper("RollbackConfig", 'set', [path])
    response_text = get_successful_response_data('prepared config rollbacked')
    return HttpResponse(response_text, JSON_CONTENT_TYPE)

@safe_rest_view
def do_upload_data(request):
    if request.method != 'PUT':
        raise RestInvalidMethodException()
    data = simplejson.loads(request.raw_post_data)
    content = data['data']
    path = data['dst']
    print "Executing config rollback with config @", path
    
    exec_os_wrapper("WriteDataToFile", 'set', [content, path])
    response_text = get_successful_response_data('written data')
    return HttpResponse(response_text, JSON_CONTENT_TYPE)

@safe_rest_view
def do_diff_config(request):
    if request.method != 'PUT':
        raise RestInvalidMethodException()
    data = simplejson.loads(request.raw_post_data)
    config1 = data['config-1']
    config2 = data['config-2']
    print "diffing '%s' with '%s'" %(config1, config2)
    
    result = exec_os_wrapper("DiffConfig", 'set', [config1, config2])
    return HttpResponse(simplejson.dumps(result), JSON_CONTENT_TYPE)

@safe_rest_view
def do_extract_upgrade_pkg_manifest(request):
    """
    This calls an oswrapper that extracts the upgrade package.
    This returns the install package 'manifest'.
    """
    if request.method != 'GET':
        raise RestInvalidMethodException()
    exec_os_wrapper("GetLatestUpgradePkg", 'get', [])
    output = exec_os_wrapper("CatUpgradeImagesFile", 'get')
    upgradePkg = output['out'].strip()
    exec_os_wrapper("ExtractUpgradePkgManifest", 'set', [upgradePkg])
    output = exec_os_wrapper("ExtractUpgradePkgManifest", 'get')
    manifest = output['out']
    return HttpResponse(manifest, JSON_CONTENT_TYPE)

@safe_rest_view
def do_extract_upgrade_pkg(request):
    if request.method != 'GET':
        raise RestInvalidMethodException()
    exec_os_wrapper("GetLatestUpgradePkg", 'get', [])
    output = exec_os_wrapper("CatUpgradeImagesFile", 'get')
    upgradePkg = output['out'].strip()
    exec_os_wrapper("ExtractUpgradePkg", 'set', [upgradePkg])
    return HttpResponse('{"status": "OK"}', JSON_CONTENT_TYPE)

@safe_rest_view
def do_get_upgrade_pkg(request):
    """
    This calls an oswrapper to get the latest upgrade
    package uploaded to the controller.
    """
    if request.method != 'GET':
        raise RestInvalidMethodException()
    exec_os_wrapper("GetLatestUpgradePkg", 'get')
    result = exec_os_wrapper("CatUpgradeImagesFile", 'get')
    jsondict = {'file': result['out'].strip()}
    return HttpResponse(simplejson.dumps(jsondict), JSON_CONTENT_TYPE)

@safe_rest_view
def do_cleanup_old_pkgs(request):
    if request.method != 'GET':
        raise RestInvalidMethodException()
    exec_os_wrapper("CleanupOldUpgradeImages", 'get')
    return HttpResponse('{"status": "OK"}', JSON_CONTENT_TYPE)

@safe_rest_view
def do_execute_upgrade_step(request):
    """
    Executes a particular upgrade step according to the
    upgrade package manifest.
    """
    if request.method != 'PUT':
        raise RestInvalidMethodException()

    put_data = json.loads(request.raw_post_data)
    imageName = put_data.get('imageName')
    stepNum = put_data.get('step')
    force = put_data.get('force')
    
    args = [stepNum, imageName]
    if force:
        args.append("--force")
    result = exec_os_wrapper("ExecuteUpgradeStep", 'get', 
                             args)
    jsondict = {}
    if len(str(result['err']).strip()) > 0:
        jsondict['status'] = "ERROR"
        jsondict['description'] = str(result['err']).strip()
    else:
        jsondict['status'] = "OK"
        jsondict['description'] = str(result['out']).strip()

    return HttpResponse(simplejson.dumps(jsondict), JSON_CONTENT_TYPE)
    
