#
# 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
    """
    if request.method != 'GET':
        raise RestInvalidMethodException()
    url = controller_url('core', 'switch', dpid, stattype, '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_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)
    
