from core.models import Site
from core.models import *
from openstack.manager import OpenStackManager

from django.contrib import admin
from django.contrib.auth.models import Group
from django import forms
from django.utils.safestring import mark_safe
from django.contrib.auth.admin import UserAdmin
from django.contrib.admin.widgets import FilteredSelectMultiple
from django.contrib.auth.forms import ReadOnlyPasswordHashField, AdminPasswordChangeForm
from django.contrib.auth.signals import user_logged_in
from django.utils import timezone
from django.contrib.contenttypes import generic
from suit.widgets import LinkedSelect
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse, NoReverseMatch
from cgi import escape as html_escape

import django_evolution
import threading

# thread locals necessary to work around a django-suit issue
_thread_locals = threading.local()

def backend_icon(obj): # backend_status, enacted, updated):
    #return "%s %s %s" % (str(obj.updated), str(obj.enacted), str(obj.backend_status))
    if (obj.enacted is not None) and obj.enacted >= obj.updated:
        return '<span style="min-width:16px;"><img src="/static/admin/img/icon_success.gif"></span>'
    else:
        if obj.backend_status == "Provisioning in progress" or obj.backend_status=="":
            return '<span style="min-width:16px;" title="%s"><img src="/static/admin/img/icon_clock.gif"></span>' % obj.backend_status
        else:
            return '<span style="min-width:16px;" title="%s"><img src="/static/admin/img/icon_error.gif"></span>' % html_escape(obj.backend_status, quote=True)

def backend_text(obj):
    icon = backend_icon(obj)
    if (obj.enacted is not None) and obj.enacted >= obj.updated:
        return "%s %s" % (icon, "successfully enacted")
    else:
        return "%s %s" % (icon, html_escape(obj.backend_status, quote=True))

class PlainTextWidget(forms.HiddenInput):
    input_type = 'hidden'

    def render(self, name, value, attrs=None):
        if value is None:
            value = ''
        return mark_safe(str(value) + super(PlainTextWidget, self).render(name, value, attrs))

class PermissionCheckingAdminMixin(object):
    # call save_by_user and delete_by_user instead of save and delete

    def has_add_permission(self, request, obj=None):
        return (not self.__user_is_readonly(request))

    def has_delete_permission(self, request, obj=None):
        return (not self.__user_is_readonly(request))

    def save_model(self, request, obj, form, change):
        if self.__user_is_readonly(request):
            # this 'if' might be redundant if save_by_user is implemented right
            raise PermissionDenied

        obj.caller = request.user
        # update openstack connection to use this site/tenant
        obj.save_by_user(request.user)

    def delete_model(self, request, obj):
        obj.delete_by_user(request.user)

    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for instance in instances:
            instance.save_by_user(request.user)

        # BUG in django 1.7? Objects are not deleted by formset.save if
        # commit is False. So let's delete them ourselves.
        #
        # code from forms/models.py save_existing_objects()
        try:
            forms_to_delete = formset.deleted_forms
        except AttributeError:
            forms_to_delete = []
        if formset.initial_forms:
            for form in formset.initial_forms:
                obj = form.instance
                if form in forms_to_delete:
                    if obj.pk is None:
                        continue
                    formset.deleted_objects.append(obj)
                    obj.delete()

        formset.save_m2m()

    def get_actions(self,request):
        actions = super(PermissionCheckingAdminMixin,self).get_actions(request)

        if self.__user_is_readonly(request):
            if 'delete_selected' in actions:
                del actions['delete_selected']

        return actions

    def change_view(self,request,object_id, extra_context=None):
        if self.__user_is_readonly(request):
            if not hasattr(self, "readonly_save"):
                # save the original readonly fields
                self.readonly_save = self.readonly_fields
                self.inlines_save = self.inlines
            if hasattr(self, "user_readonly_fields"):
                self.readonly_fields=self.user_readonly_fields
            if hasattr(self, "user_readonly_inlines"):
                self.inlines = self.user_readonly_inlines
        else:
            if hasattr(self, "readonly_save"):
                # restore the original readonly fields
                self.readonly_fields = self.readonly_save
            if hasattr(self, "inlines_save"):
                self.inlines = self.inlines_save

        try:
            return super(PermissionCheckingAdminMixin, self).change_view(request, object_id, extra_context=extra_context)
        except PermissionDenied:
            pass
        if request.method == 'POST':
            raise PermissionDenied
        request.readonly = True
        return super(PermissionCheckingAdminMixin, self).change_view(request, object_id, extra_context=extra_context)

    def __user_is_readonly(self, request):
        return request.user.isReadOnlyUser()

    def backend_status_text(self, obj):
        return mark_safe(backend_text(obj))

    def backend_status_icon(self, obj):
        return mark_safe(backend_icon(obj))
    backend_status_icon.short_description = ""

    def get_form(self, request, obj=None):
        # Save obj and request in thread-local storage, so suit_form_tabs can
        # use it to determine whether we're in edit or add mode, and can
        # determine whether the user is an admin.
        _thread_locals.request = request
        _thread_locals.obj = obj
        return super(PermissionCheckingAdminMixin, self).get_form(request, obj)

    def get_inline_instances(self, request, obj=None):
        inlines = super(PermissionCheckingAdminMixin, self).get_inline_instances(request, obj)

        # inlines that should only be shown to an admin user
        if request.user.is_admin:
            for inline_class in getattr(self, "admin_inlines", []):
                inlines.append(inline_class(self.model, self.admin_site))

        return inlines

class ReadOnlyAwareAdmin(PermissionCheckingAdminMixin, admin.ModelAdmin):
    # Note: Make sure PermissionCheckingAdminMixin is listed before
    # admin.ModelAdmin in the class declaration.

    pass

class PlanetStackBaseAdmin(ReadOnlyAwareAdmin):
    save_on_top = False

class SingletonAdmin (ReadOnlyAwareAdmin):
    def has_add_permission(self, request):
        if not super(SingletonAdmin, self).has_add_permission(request):
            return False

        num_objects = self.model.objects.count()
        if num_objects >= 1:
            return False
        else:
            return True

class PlStackTabularInline(admin.TabularInline):
    def __init__(self, *args, **kwargs):
        super(PlStackTabularInline, self).__init__(*args, **kwargs)

        # InlineModelAdmin as no get_fields() method, so in order to add
        # the selflink field, we override __init__ to modify self.fields and
        # self.readonly_fields.

        self.setup_selflink()

    def get_change_url(self, model, id):
        """ Get the URL to a change form in the admin for this model """
        reverse_path = "admin:%s_change" % (model._meta.db_table)
        try:
            url = reverse(reverse_path, args=(id,))
        except NoReverseMatch:
            return None

        return url

    def setup_selflink(self):
        if hasattr(self, "selflink_fieldname"):
            """ self.selflink_model can be defined to punch through a relation
                to its target object. For example, in SliceNetworkInline, set
                selflink_model = "network", and the URL will lead to the Network
                object instead of trying to bring up a change view of the
                SliceNetwork object.
            """
            self.selflink_model = getattr(self.model,self.selflink_fieldname).field.rel.to
        else:
            self.selflink_model = self.model

        url = self.get_change_url(self.selflink_model, 0)

        # We don't have an admin for this object, so don't create the
        # selflink.
        if (url == None):
            return

        # Since we need to add "selflink" to the field list, we need to create
        # self.fields if it is None.
        if (self.fields is None):
            self.fields = []
            for f in self.model._meta.fields:
                if f.editable and f.name != "id":
                    self.fields.append(f.name)

        self.fields = tuple(self.fields) + ("selflink", )

        if self.readonly_fields is None:
            self.readonly_fields = ()

        self.readonly_fields = tuple(self.readonly_fields) + ("selflink", )

    def selflink(self, obj):
        if hasattr(self, "selflink_fieldname"):
            obj = getattr(obj, self.selflink_fieldname)

        if obj.id:
            url = self.get_change_url(self.selflink_model, obj.id)
            return "<a href='%s'>Details</a>" % str(url)
        else:
            return "Not present"

    selflink.allow_tags = True
    selflink.short_description = "Details"

    def has_add_permission(self, request):
        return not request.user.isReadOnlyUser()

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = list(self.readonly_fields)[:]
        if request.user.isReadOnlyUser():
            for field in self.fields:
                if not field in readonly_fields:
                    readonly_fields.append(field)
        return readonly_fields

    def backend_status_icon(self, obj):
        return mark_safe(backend_icon(obj))
    backend_status_icon.short_description = ""

class PlStackGenericTabularInline(generic.GenericTabularInline):
    def has_add_permission(self, request):
        return not request.user.isReadOnlyUser()

    def get_readonly_fields(self, request, obj=None):
        readonly_fields = list(self.readonly_fields)[:]
        if request.user.isReadOnlyUser():
            for field in self.fields:
                if not field in readonly_fields:
                    readonly_fields.append(field)
        return readonly_fields

    def backend_status_icon(self, obj):
        return mark_safe(backend_icon(obj))
    backend_status_icon.short_description = ""

class ReservationInline(PlStackTabularInline):
    model = Reservation
    extra = 0
    suit_classes = 'suit-tab suit-tab-reservations'

    def queryset(self, request):
        return Reservation.select_by_user(request.user)

class TagInline(PlStackGenericTabularInline):
    model = Tag
    extra = 0
    suit_classes = 'suit-tab suit-tab-tags'
    fields = ['service', 'name', 'value']

    def queryset(self, request):
        return Tag.select_by_user(request.user)

class NetworkLookerUpper:
    """ This is a callable that looks up a network name in a sliver and returns
        the ip address for that network.
    """

    byNetworkName = {}    # class variable

    def __init__(self, name):
        self.short_description = name
        self.__name__ = name
        self.network_name = name

    def __call__(self, obj):
        if obj is not None:
            for nbs in obj.networksliver_set.all():
                if (nbs.network.name == self.network_name):
                    return nbs.ip
        return ""

    def __str__(self):
        return self.network_name

    @staticmethod
    def get(network_name):
        """ We want to make sure we alwars return the same NetworkLookerUpper
            because sometimes django will cause them to be instantiated multiple
            times (and we don't want different ones in form.fields vs
            SliverInline.readonly_fields).
        """
        if network_name not in NetworkLookerUpper.byNetworkName:
            NetworkLookerUpper.byNetworkName[network_name] = NetworkLookerUpper(network_name)
        return NetworkLookerUpper.byNetworkName[network_name]

class SliverInline(PlStackTabularInline):
    model = Sliver
    fields = ['backend_status_icon', 'all_ips_string', 'instance_name', 'slice', 'deploymentNetwork', 'flavor', 'image', 'node']
    extra = 0
    readonly_fields = ['backend_status_icon', 'all_ips_string', 'instance_name']
    suit_classes = 'suit-tab suit-tab-slivers'

    def queryset(self, request):
        return Sliver.select_by_user(request.user)

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        if db_field.name == 'deploymentNetwork':
           kwargs['queryset'] = Deployment.select_by_acl(request.user)
           kwargs['widget'] = forms.Select(attrs={'onChange': "sliver_deployment_changed(this);"})
        elif db_field.name == 'flavor':
           kwargs['widget'] = forms.Select(attrs={'onChange': "sliver_flavor_changed(this);"})

        field = super(SliverInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

        return field

class SiteInline(PlStackTabularInline):
    model = Site
    extra = 0
    suit_classes = 'suit-tab suit-tab-sites'

    def queryset(self, request):
        return Site.select_by_user(request.user)

class UserInline(PlStackTabularInline):
    model = User
    fields = ['backend_status_icon', 'email', 'firstname', 'lastname']
    readonly_fields = ('backend_status_icon', )
    extra = 0
    suit_classes = 'suit-tab suit-tab-users'

    def queryset(self, request):
        return User.select_by_user(request.user)

class SliceInline(PlStackTabularInline):
    model = Slice
    fields = ['backend_status_icon', 'name', 'site', 'serviceClass', 'service']
    readonly_fields = ('backend_status_icon', )
    extra = 0
    suit_classes = 'suit-tab suit-tab-slices'

    def queryset(self, request):
        return Slice.select_by_user(request.user)

class NodeInline(PlStackTabularInline):
    model = Node
    extra = 0
    suit_classes = 'suit-tab suit-tab-nodes'
    fields = ['backend_status_icon', 'name','deployment','site']
    readonly_fields = ('backend_status_icon', )

class DeploymentPrivilegeInline(PlStackTabularInline):
    model = DeploymentPrivilege
    extra = 0
    suit_classes = 'suit-tab suit-tab-deploymentprivileges'
    fields = ['backend_status_icon', 'user','role','deployment']
    readonly_fields = ('backend_status_icon', )

    def queryset(self, request):
        return DeploymentPrivilege.select_by_user(request.user)

class SitePrivilegeInline(PlStackTabularInline):
    model = SitePrivilege
    extra = 0
    suit_classes = 'suit-tab suit-tab-siteprivileges'
    fields = ['backend_status_icon', 'user','site', 'role']
    readonly_fields = ('backend_status_icon', )

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'site':
            kwargs['queryset'] = Site.select_by_user(request.user)

        if db_field.name == 'user':
            kwargs['queryset'] = User.select_by_user(request.user)
        return super(SitePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        return SitePrivilege.select_by_user(request.user)

class SiteDeploymentInline(PlStackTabularInline):
    model = SiteDeployments
    extra = 0
    suit_classes = 'suit-tab suit-tab-deployments'
    fields = ['backend_status_icon', 'deployment','site']
    readonly_fields = ('backend_status_icon', )

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'site':
            kwargs['queryset'] = Site.select_by_user(request.user)

        if db_field.name == 'deployment':
            kwargs['queryset'] = Deployment.select_by_user(request.user)
        return super(SiteDeploymentInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        return SiteDeployments.select_by_user(request.user)


class SlicePrivilegeInline(PlStackTabularInline):
    model = SlicePrivilege
    suit_classes = 'suit-tab suit-tab-sliceprivileges'
    extra = 0
    fields = ('backend_status_icon', 'user', 'slice', 'role')
    readonly_fields = ('backend_status_icon', )

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'slice':
           kwargs['queryset'] = Slice.select_by_user(request.user)
        if db_field.name == 'user':
           kwargs['queryset'] = User.select_by_user(request.user)

        return super(SlicePrivilegeInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        return SlicePrivilege.select_by_user(request.user)

class SliceNetworkInline(PlStackTabularInline):
    model = Network.slices.through
    selflink_fieldname = "network"
    extra = 0
    verbose_name = "Network Connection"
    verbose_name_plural = "Network Connections"
    suit_classes = 'suit-tab suit-tab-slicenetworks'
    fields = ['backend_status_icon', 'network']
    readonly_fields = ('backend_status_icon', )

class ImageDeploymentsInline(PlStackTabularInline):
    model = ImageDeployments
    extra = 0
    verbose_name = "Image Deployments"
    verbose_name_plural = "Image Deployments"
    suit_classes = 'suit-tab suit-tab-imagedeployments'
    fields = ['backend_status_icon', 'image', 'deployment', 'glance_image_id']
    readonly_fields = ['backend_status_icon', 'glance_image_id']

class SliceRoleAdmin(PlanetStackBaseAdmin):
    model = SliceRole
    pass

class SiteRoleAdmin(PlanetStackBaseAdmin):
    model = SiteRole
    pass

class DeploymentAdminForm(forms.ModelForm):
    sites = forms.ModelMultipleChoiceField(
        queryset=Site.objects.all(),
        required=False,
        help_text="Select which sites are allowed to host nodes in this deployment",
        widget=FilteredSelectMultiple(
            verbose_name=('Sites'), is_stacked=False
        )
    )
    images = forms.ModelMultipleChoiceField(
        queryset=Image.objects.all(),
        required=False,
        help_text="Select which images should be deployed on this deployment",
        widget=FilteredSelectMultiple(
            verbose_name=('Images'), is_stacked=False
        )
    )
    flavors = forms.ModelMultipleChoiceField(
        queryset=Flavor.objects.all(),
        required=False,
        help_text="Select which flavors should be usable on this deployment",
        widget=FilteredSelectMultiple(
            verbose_name=('Flavors'), is_stacked=False
        )
    )
    class Meta:
        model = Deployment
        many_to_many = ["flavors",]

    def __init__(self, *args, **kwargs):
      request = kwargs.pop('request', None)
      super(DeploymentAdminForm, self).__init__(*args, **kwargs)

      self.fields['accessControl'].initial = "allow site " + request.user.site.name

      if self.instance and self.instance.pk:
        self.fields['sites'].initial = [x.site for x in self.instance.sitedeployments_set.all()]
        self.fields['images'].initial = [x.image for x in self.instance.imagedeployments_set.all()]
        self.fields['flavors'].initial = self.instance.flavors.all()

    def manipulate_m2m_objs(self, this_obj, selected_objs, all_relations, relation_class, local_attrname, foreign_attrname):
        """ helper function for handling m2m relations from the MultipleChoiceField

            this_obj: the source object we want to link from

            selected_objs: a list of destination objects we want to link to

            all_relations: the full set of relations involving this_obj, including ones we don't want

            relation_class: the class that implements the relation from source to dest

            local_attrname: field name representing this_obj in relation_class

            foreign_attrname: field name representing selected_objs in relation_class

            This function will remove all newobjclass relations from this_obj
            that are not contained in selected_objs, and add any relations that
            are in selected_objs but don't exist in the data model yet.
        """

        existing_dest_objs = []
        for relation in list(all_relations):
            if getattr(relation, foreign_attrname) not in selected_objs:
                #print "deleting site", sdp.site
                relation.delete()
            else:
                existing_dest_objs.append(getattr(relation, foreign_attrname))

        for dest_obj in selected_objs:
            if dest_obj not in existing_dest_objs:
                #print "adding site", site
                kwargs = {foreign_attrname: dest_obj, local_attrname: this_obj}
                relation = relation_class(**kwargs)
                relation.save()

    def save(self, commit=True):
      deployment = super(DeploymentAdminForm, self).save(commit=False)

      if commit:
        deployment.save()
        # this has to be done after save() if/when a deployment is first created
        deployment.flavors = self.cleaned_data['flavors']

      if deployment.pk:
        # save_m2m() doesn't seem to work with 'through' relations. So we
        #    create/destroy the through models ourselves. There has to be
        #    a better way...

        self.manipulate_m2m_objs(deployment, self.cleaned_data['sites'], deployment.sitedeployments_set.all(), SiteDeployments, "deployment", "site")
        self.manipulate_m2m_objs(deployment, self.cleaned_data['images'], deployment.imagedeployments_set.all(), ImageDeployments, "deployment", "image")

      self.save_m2m()

      return deployment

class DeploymentAdminROForm(DeploymentAdminForm):
    def save(self, commit=True):
        raise PermissionDenied

class SiteAssocInline(PlStackTabularInline):
    model = Site.deployments.through
    extra = 0
    suit_classes = 'suit-tab suit-tab-sites'

class DeploymentAdmin(PlanetStackBaseAdmin):
    model = Deployment
    fieldList = ['backend_status_text', 'name', 'availability_zone', 'sites', 'images', 'flavors', 'accessControl']
    fieldsets = [(None, {'fields': fieldList, 'classes':['suit-tab suit-tab-sites']})]
    inlines = [DeploymentPrivilegeInline,NodeInline,TagInline] # ,ImageDeploymentsInline]
    list_display = ['backend_status_icon', 'name']
    list_display_links = ('backend_status_icon', 'name', )
    readonly_fields = ('backend_status_text', )

    user_readonly_fields = ['name']

    suit_form_tabs =(('sites','Deployment Details'),('nodes','Nodes'),('deploymentprivileges','Privileges'),('tags','Tags')) # ,('imagedeployments','Images'))

    def get_form(self, request, obj=None, **kwargs):
        if request.user.isReadOnlyUser():
            kwargs["form"] = DeploymentAdminROForm
        else:
            kwargs["form"] = DeploymentAdminForm
        adminForm = super(DeploymentAdmin,self).get_form(request, obj, **kwargs)

        # from stackexchange: pass the request object into the form

        class AdminFormMetaClass(adminForm):
           def __new__(cls, *args, **kwargs):
               kwargs['request'] = request
               return adminForm(*args, **kwargs)

        return AdminFormMetaClass

class ServiceAttrAsTabInline(PlStackTabularInline):
    model = ServiceAttribute
    fields = ['name','value']
    extra = 0
    suit_classes = 'suit-tab suit-tab-serviceattrs'

class ServiceAdmin(PlanetStackBaseAdmin):
    list_display = ("backend_status_icon","name","description","versionNumber","enabled","published")
    list_display_links = ('backend_status_icon', 'name', )
    fieldList = ["backend_status_text","name","description","versionNumber","enabled","published"]
    fieldsets = [(None, {'fields': fieldList, 'classes':['suit-tab suit-tab-general']})]
    inlines = [ServiceAttrAsTabInline,SliceInline]
    readonly_fields = ('backend_status_text', )

    user_readonly_fields = fieldList

    suit_form_tabs =(('general', 'Service Details'),
        ('slices','Slices'),
        ('serviceattrs','Additional Attributes'),
    )

class SiteAdmin(PlanetStackBaseAdmin):
    fieldList = ['backend_status_text', 'name', 'site_url', 'enabled', 'is_public', 'login_base', 'accountLink','location']
    fieldsets = [
        (None, {'fields': fieldList, 'classes':['suit-tab suit-tab-general']}),
        #('Deployment Networks', {'fields': ['deployments'], 'classes':['suit-tab suit-tab-deployments']}),
    ]
    suit_form_tabs =(('general', 'Site Details'),
        ('users','Users'),
        ('siteprivileges','Privileges'),
        ('deployments','Deployments'),
        ('slices','Slices'),
        ('nodes','Nodes'),
        ('tags','Tags'),
    )
    readonly_fields = ['backend_status_text', 'accountLink']

    user_readonly_fields = ['name', 'deployments','site_url', 'enabled', 'is_public', 'login_base', 'accountLink']

    list_display = ('backend_status_icon', 'name', 'login_base','site_url', 'enabled')
    list_display_links = ('backend_status_icon', 'name', )
    filter_horizontal = ('deployments',)
    inlines = [SliceInline,UserInline,TagInline, NodeInline, SitePrivilegeInline, SiteDeploymentInline]
    search_fields = ['name']

    def queryset(self, request):
        return Site.select_by_user(request.user)

    def get_formsets(self, request, obj=None):
        for inline in self.get_inline_instances(request, obj):
            # hide MyInline in the add view
            if obj is None:
                continue
            if isinstance(inline, SliverInline):
                inline.model.caller = request.user
            yield inline.get_formset(request, obj)

    def accountLink(self, obj):
        link_obj = obj.accounts.all()
        if link_obj:
            reverse_path = "admin:core_account_change"
            url = reverse(reverse_path, args =(link_obj[0].id,))
            return "<a href='%s'>%s</a>" % (url, "view billing details")
        else:
            return "no billing data for this site"
    accountLink.allow_tags = True
    accountLink.short_description = "Billing"

    def save_model(self, request, obj, form, change):
        # update openstack connection to use this site/tenant
        obj.save_by_user(request.user) 

    def delete_model(self, request, obj):
        obj.delete_by_user(request.user)
        

class SitePrivilegeAdmin(PlanetStackBaseAdmin):
    fieldList = ['backend_status_text', 'user', 'site', 'role']
    fieldsets = [
        (None, {'fields': fieldList, 'classes':['collapse']})
    ]
    readonly_fields = ('backend_status_text', )
    list_display = ('backend_status_icon', 'user', 'site', 'role')
    list_display_links = list_display
    user_readonly_fields = fieldList
    user_readonly_inlines = []

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'site':
            if not request.user.is_admin:
                # only show sites where user is an admin or pi
                sites = set()
                for site_privilege in SitePrivilege.objects.filer(user=request.user):
                    if site_privilege.role.role_type in ['admin', 'pi']:
                        sites.add(site_privilege.site)
                kwargs['queryset'] = Site.objects.filter(site__in=list(sites))

        if db_field.name == 'user':
            if not request.user.is_admin:
                # only show users from sites where caller has admin or pi role
                roles = Role.objects.filter(role_type__in=['admin', 'pi'])
                site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
                sites = [site_privilege.site for site_privilege in site_privileges]
                site_privileges = SitePrivilege.objects.filter(site__in=sites)
                emails = [site_privilege.user.email for site_privilege in site_privileges]
                users = User.objects.filter(email__in=emails)
                kwargs['queryset'] = users

        return super(SitePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        # admins can see all privileges. Users can only see privileges at sites
        # where they have the admin role or pi role.
        qs = super(SitePrivilegeAdmin, self).queryset(request)
        #if not request.user.is_admin:
        #    roles = Role.objects.filter(role_type__in=['admin', 'pi'])
        #    site_privileges = SitePrivilege.objects.filter(user=request.user).filter(role__in=roles)
        #    login_bases = [site_privilege.site.login_base for site_privilege in site_privileges]
        #    sites = Site.objects.filter(login_base__in=login_bases)
        #    qs = qs.filter(site__in=sites)
        return qs

class SliceForm(forms.ModelForm):
    class Meta:
        model = Slice
        widgets = {
            'service': LinkedSelect
        }

    def clean(self):
        cleaned_data = super(SliceForm, self).clean()
        name = cleaned_data.get('name')
        site = cleaned_data.get('site')
        if (not isinstance(site,Site)):
            # previous code indicates 'site' could be a site_id and not a site?
            site = Slice.objects.get(id=site.id)
        if not name.startswith(site.login_base):
            raise forms.ValidationError('slice name must begin with %s' % site.login_base)
        return cleaned_data

class SliceDeploymentsInline(PlStackTabularInline):
    model = SliceDeployments
    extra = 0
    verbose_name = "Slice Deployment"
    verbose_name_plural = "Slice Deployments"
    suit_classes = 'suit-tab suit-tab-admin-only'
    fields = ['backend_status_icon', 'deployment', 'tenant_id']
    readonly_fields = ('backend_status_icon', )

class SliceAdmin(PlanetStackBaseAdmin):
    form = SliceForm
    fieldList = ['backend_status_text', 'site', 'name', 'serviceClass', 'enabled','description', 'service', 'slice_url', 'max_slivers']
    fieldsets = [('Slice Details', {'fields': fieldList, 'classes':['suit-tab suit-tab-general']}),]
    readonly_fields = ('backend_status_text', )
    list_display = ('backend_status_icon', 'name', 'site','serviceClass', 'slice_url', 'max_slivers')
    list_display_links = ('backend_status_icon', 'name', )
    inlines = [SlicePrivilegeInline,SliverInline, TagInline, ReservationInline,SliceNetworkInline]
    admin_inlines = [SliceDeploymentsInline]

    user_readonly_fields = fieldList

    @property
    def suit_form_tabs(self):
        tabs =[('general', 'Slice Details'),
          ('slicenetworks','Networks'),
          ('sliceprivileges','Privileges'),
          ('slivers','Slivers'),
          ('tags','Tags'),
          ('reservations','Reservations'),
          ]

        request=getattr(_thread_locals, "request", None)
        if request and request.user.is_admin:
            tabs.append( ('admin-only', 'Admin-Only') )

        return tabs

    def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
        deployment_nodes = []
        for node in Node.objects.all():
            deployment_nodes.append( (node.deployment.id, node.id, node.name) )

        deployment_flavors = []
        for flavor in Flavor.objects.all():
            for deployment in flavor.deployments.all():
                deployment_flavors.append( (deployment.id, flavor.id, flavor.name) )

        deployment_images = []
        for image in Image.objects.all():
            for imageDeployment in image.imagedeployments_set.all():
                deployment_images.append( (imageDeployment.deployment.id, image.id, image.name) )

        site_login_bases = []
        for site in Site.objects.all():
            site_login_bases.append((site.id, site.login_base))

        context["deployment_nodes"] = deployment_nodes
        context["deployment_flavors"] = deployment_flavors
        context["deployment_images"] = deployment_images
        context["site_login_bases"] = site_login_bases
        return super(SliceAdmin, self).render_change_form(request, context, add, change, form_url, obj)

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'site':
            kwargs['queryset'] = Site.select_by_user(request.user)
            kwargs['widget'] = forms.Select(attrs={'onChange': "update_slice_prefix(this, $($(this).closest('fieldset')[0]).find('.field-name input')[0].id)"})

        return super(SliceAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        # admins can see all keys. Users can only see slices they belong to.
        return Slice.select_by_user(request.user)

    def get_formsets(self, request, obj=None):
        for inline in self.get_inline_instances(request, obj):
            # hide MyInline in the add view
            if obj is None:
                continue
            if isinstance(inline, SliverInline):
                inline.model.caller = request.user
            yield inline.get_formset(request, obj)

class SlicePrivilegeAdmin(PlanetStackBaseAdmin):
    fieldsets = [
        (None, {'fields': ['backend_status_text', 'user', 'slice', 'role']})
    ]
    readonly_fields = ('backend_status_text', )
    list_display = ('backend_status_icon', 'user', 'slice', 'role')
    list_display_links = list_display

    user_readonly_fields = ['user', 'slice', 'role']
    user_readonly_inlines = []

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'slice':
            kwargs['queryset'] = Slice.select_by_user(request.user)
        
        if db_field.name == 'user':
            kwargs['queryset'] = User.select_by_user(request.user)

        return super(SlicePrivilegeAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        # admins can see all memberships. Users can only see memberships of
        # slices where they have the admin role.
        return SlicePrivilege.select_by_user(request.user)

    def save_model(self, request, obj, form, change):
        # update openstack connection to use this site/tenant
        auth = request.session.get('auth', {})
        auth['tenant'] = obj.slice.slicename
        obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
        obj.save()

    def delete_model(self, request, obj):
        # update openstack connection to use this site/tenant
        auth = request.session.get('auth', {})
        auth['tenant'] = obj.slice.slicename
        obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
        obj.delete()


class ImageAdmin(PlanetStackBaseAdmin):

    fieldsets = [('Image Details',
                   {'fields': ['backend_status_text', 'name', 'disk_format', 'container_format'],
                    'classes': ['suit-tab suit-tab-general']})
               ]
    readonly_fields = ('backend_status_text', )

    suit_form_tabs =(('general','Image Details'),('slivers','Slivers'),('imagedeployments','Deployments'))

    inlines = [SliverInline, ImageDeploymentsInline]

    user_readonly_fields = ['name', 'disk_format', 'container_format']

    list_display = ['backend_status_icon', 'name']
    list_display_links = ('backend_status_icon', 'name', )

class NodeForm(forms.ModelForm):
    class Meta:
        widgets = {
            'site': LinkedSelect,
            'deployment': LinkedSelect
        }

class NodeAdmin(PlanetStackBaseAdmin):
    form = NodeForm
    list_display = ('backend_status_icon', 'name', 'site', 'deployment')
    list_display_links = ('backend_status_icon', 'name', )
    list_filter = ('deployment',)

    inlines = [TagInline,SliverInline]
    fieldsets = [('Node Details', {'fields': ['backend_status_text', 'name','site','deployment'], 'classes':['suit-tab suit-tab-details']})]
    readonly_fields = ('backend_status_text', )

    user_readonly_fields = ['name','site','deployment']
    user_readonly_inlines = [TagInline,SliverInline]

    suit_form_tabs =(('details','Node Details'),('slivers','Slivers'),('tags','Tags'))


class SliverForm(forms.ModelForm):
    class Meta:
        model = Sliver
        ip = forms.CharField(widget=PlainTextWidget)
        instance_name = forms.CharField(widget=PlainTextWidget)
        widgets = {
            'ip': PlainTextWidget(),
            'instance_name': PlainTextWidget(),
            'slice': LinkedSelect,
            'deploymentNetwork': LinkedSelect,
            'node': LinkedSelect,
            'image': LinkedSelect
        }

class TagAdmin(PlanetStackBaseAdmin):
    list_display = ['backend_status_icon', 'service', 'name', 'value', 'content_type', 'content_object',]
    list_display_links = list_display
    user_readonly_fields = ['service', 'name', 'value', 'content_type', 'content_object',]
    user_readonly_inlines = []

class SliverAdmin(PlanetStackBaseAdmin):
    form = SliverForm
    fieldsets = [
        ('Sliver Details', {'fields': ['backend_status_text', 'slice', 'deploymentNetwork', 'node', 'ip', 'instance_name', 'flavor', 'image', ], 'classes': ['suit-tab suit-tab-general'], })
    ]
    readonly_fields = ('backend_status_text', )
    list_display = ['backend_status_icon', 'ip', 'instance_name', 'slice', 'flavor', 'image', 'node', 'deploymentNetwork']
    list_display_links = ('backend_status_icon', 'ip',)

    suit_form_tabs =(('general', 'Sliver Details'),
        ('tags','Tags'),
    )

    inlines = [TagInline]

    user_readonly_fields = ['slice', 'deploymentNetwork', 'node', 'ip', 'instance_name', 'flavor', 'image']

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'slice':
            kwargs['queryset'] = Slice.select_by_user(request.user)

        return super(SliverAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        # admins can see all slivers. Users can only see slivers of
        # the slices they belong to.
        return Sliver.select_by_user(request.user)


    def get_formsets(self, request, obj=None):
        # make some fields read only if we are updating an existing record
        if obj == None:
            #self.readonly_fields = ('ip', 'instance_name')
            self.readonly_fields = ('backend_status_text',)
        else:
            self.readonly_fields = ('backend_status_text',)
            #self.readonly_fields = ('ip', 'instance_name', 'slice', 'image', 'key')

        for inline in self.get_inline_instances(request, obj):
            # hide MyInline in the add view
            if obj is None:
                continue
            if isinstance(inline, SliverInline):
                inline.model.caller = request.user
            yield inline.get_formset(request, obj)

    #def save_model(self, request, obj, form, change):
    #    # update openstack connection to use this site/tenant
    #    auth = request.session.get('auth', {})
    #    auth['tenant'] = obj.slice.name
    #    obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
    #    obj.creator = request.user
    #    obj.save()

    #def delete_model(self, request, obj):
    #    # update openstack connection to use this site/tenant
    #    auth = request.session.get('auth', {})
    #    auth['tenant'] = obj.slice.name
    #    obj.os_manager = OpenStackManager(auth=auth, caller=request.user)
    #    obj.delete()

class UserCreationForm(forms.ModelForm):
    """A form for creating new users. Includes all the required
    fields, plus a repeated password."""
    password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
    password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)

    class Meta:
        model = User
        fields = ('email', 'firstname', 'lastname', 'phone', 'public_key')

    def clean_password2(self):
        # Check that the two password entries match
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return password2

    def save(self, commit=True):
        # Save the provided password in hashed format
        user = super(UserCreationForm, self).save(commit=False)
        user.password = self.cleaned_data["password1"]
        #user.set_password(self.cleaned_data["password1"])
        if commit:
            user.save()
        return user


class UserChangeForm(forms.ModelForm):
    """A form for updating users. Includes all the fields on
    the user, but replaces the password field with admin's
    password hash display field.
    """
    password = ReadOnlyPasswordHashField(label='Password',
                   help_text= '<a href=\"password/\">Change Password</a>.')

    class Meta:
        model = User

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial["password"]

class UserDashboardViewInline(PlStackTabularInline):
    model = UserDashboardView
    extra = 0
    suit_classes = 'suit-tab suit-tab-dashboards'
    fields = ['user', 'dashboardView', 'order']

class UserAdmin(PermissionCheckingAdminMixin, UserAdmin):
    # Note: Make sure PermissionCheckingAdminMixin is listed before
    # admin.ModelAdmin in the class declaration.

    class Meta:
        app_label = "core"

    # The forms to add and change user instances
    form = UserChangeForm
    add_form = UserCreationForm

    # The fields to be used in displaying the User model.
    # These override the definitions on the base UserAdmin
    # that reference specific fields on auth.User.
    list_display = ('email', 'firstname', 'lastname', 'site', 'last_login')
    list_filter = ('site',)
    inlines = [SlicePrivilegeInline,SitePrivilegeInline,DeploymentPrivilegeInline,UserDashboardViewInline]

    fieldListLoginDetails = ['backend_status_text', 'email','site','password','is_active','is_readonly','is_admin','public_key']
    fieldListContactInfo = ['firstname','lastname','phone','timezone']

    fieldsets = (
        ('Login Details', {'fields': ['backend_status_text', 'email', 'site','password', 'is_active', 'is_readonly', 'is_admin', 'public_key'], 'classes':['suit-tab suit-tab-general']}),
        ('Contact Information', {'fields': ('firstname','lastname','phone', 'timezone'), 'classes':['suit-tab suit-tab-contact']}),
        #('Dashboard Views', {'fields': ('dashboards',), 'classes':['suit-tab suit-tab-dashboards']}),
        #('Important dates', {'fields': ('last_login',)}),
    )
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('email', 'firstname', 'lastname', 'is_readonly', 'phone', 'public_key','password1', 'password2')},
        ),
    )
    readonly_fields = ('backend_status_text', )
    search_fields = ('email',)
    ordering = ('email',)
    filter_horizontal = ()

    user_readonly_fields = fieldListLoginDetails + fieldListContactInfo

    @property
    def suit_form_tabs(self):
        if getattr(_thread_locals, "obj", None) is None:
            return []
        else:
            return (('general','Login Details'),
                         ('contact','Contact Information'),
                         ('sliceprivileges','Slice Privileges'),
                         ('siteprivileges','Site Privileges'),
                         ('deploymentprivileges','Deployment Privileges'),
                         ('dashboards','Dashboard Views'))

    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'site':
            kwargs['queryset'] = Site.select_by_user(request.user)

        return super(UserAdmin, self).formfield_for_foreignkey(db_field, request, **kwargs)

    def queryset(self, request):
        return User.select_by_user(request.user)

class DashboardViewAdmin(PlanetStackBaseAdmin):
    fieldsets = [('Dashboard View Details',
                   {'fields': ['backend_status_text', 'name', 'url'],
                    'classes': ['suit-tab suit-tab-general']})
               ]
    readonly_fields = ('backend_status_text', )

    suit_form_tabs =(('general','Dashboard View Details'),)

class ServiceResourceInline(PlStackTabularInline):
    model = ServiceResource
    extra = 0

class ServiceClassAdmin(PlanetStackBaseAdmin):
    list_display = ('backend_status_icon', 'name', 'commitment', 'membershipFee')
    list_display_links = ('backend_status_icon', 'name', )
    inlines = [ServiceResourceInline]

    user_readonly_fields = ['name', 'commitment', 'membershipFee']
    user_readonly_inlines = []

class ReservedResourceInline(PlStackTabularInline):
    model = ReservedResource
    extra = 0
    suit_classes = 'suit-tab suit-tab-reservedresources'

    def formfield_for_foreignkey(self, db_field, request=None, **kwargs):
        field = super(ReservedResourceInline, self).formfield_for_foreignkey(db_field, request, **kwargs)

        if db_field.name == 'resource':
            # restrict resources to those that the slice's service class allows
            if request._slice is not None:
                field.queryset = field.queryset.filter(serviceClass = request._slice.serviceClass, calendarReservable=True)
                if len(field.queryset) > 0:
                    field.initial = field.queryset.all()[0]
            else:
                field.queryset = field.queryset.none()
        elif db_field.name == 'sliver':
            # restrict slivers to those that belong to the slice
            if request._slice is not None:
                field.queryset = field.queryset.filter(slice = request._slice)
            else:
                field.queryset = field.queryset.none()

        return field

    def queryset(self, request):
        return ReservedResource.select_by_user(request.user)

class ReservationChangeForm(forms.ModelForm):
    class Meta:
        model = Reservation
        widgets = {
            'slice' : LinkedSelect
        }

class ReservationAddForm(forms.ModelForm):
    slice = forms.ModelChoiceField(queryset=Slice.objects.all(), widget=forms.Select(attrs={"onChange":"document.getElementById('id_refresh').value=1; submit()"}))
    refresh = forms.CharField(widget=forms.HiddenInput())

    class Media:
       css = {'all': ('planetstack.css',)}   # .field-refresh { display: none; }

    def clean_slice(self):
        slice = self.cleaned_data.get("slice")
        x = ServiceResource.objects.filter(serviceClass = slice.serviceClass, calendarReservable=True)
        if len(x) == 0:
            raise forms.ValidationError("The slice you selected does not have a service class that allows reservations")
        return slice

    class Meta:
        model = Reservation
        widgets = {
            'slice' : LinkedSelect
        }


class ReservationAddRefreshForm(ReservationAddForm):
    """ This form is displayed when the Reservation Form receives an update
        from the Slice dropdown onChange handler. It doesn't validate the
        data and doesn't save the data. This will cause the form to be
        redrawn.
    """

    """ don't validate anything other than slice """
    dont_validate_fields = ("startTime", "duration")

    def full_clean(self):
        result = super(ReservationAddForm, self).full_clean()

        for fieldname in self.dont_validate_fields:
            if fieldname in self._errors:
                del self._errors[fieldname]

        return result

    """ don't save anything """
    def is_valid(self):
        return False

class ReservationAdmin(PlanetStackBaseAdmin):
    fieldList = ['backend_status_text', 'slice', 'startTime', 'duration']
    fieldsets = [('Reservation Details', {'fields': fieldList, 'classes': ['suit-tab suit-tab-general']})]
    readonly_fields = ('backend_status_text', )
    list_display = ('startTime', 'duration')
    form = ReservationAddForm

    suit_form_tabs = (('general','Reservation Details'), ('reservedresources','Reserved Resources'))

    inlines = [ReservedResourceInline]
    user_readonly_fields = fieldList

    def add_view(self, request, form_url='', extra_context=None):
        timezone.activate(request.user.timezone)
        request._refresh = False
        request._slice = None
        if request.method == 'POST':
            # "refresh" will be set to "1" if the form was submitted due to
            # a change in the Slice dropdown.
            if request.POST.get("refresh","1") == "1":
                request._refresh = True
                request.POST["refresh"] = "0"

            # Keep track of the slice that was selected, so the
            # reservedResource inline can filter items for the slice.
            request._slice = request.POST.get("slice",None)
            if (request._slice is not None):
                request._slice = Slice.objects.get(id=request._slice)

        result =  super(ReservationAdmin, self).add_view(request, form_url, extra_context)
        return result

    def changelist_view(self, request, extra_context = None):
        timezone.activate(request.user.timezone)
        return super(ReservationAdmin, self).changelist_view(request, extra_context)

    def get_form(self, request, obj=None, **kwargs):
        request._obj_ = obj
        if obj is not None:
            # For changes, set request._slice to the slice already set in the
            # object.
            request._slice = obj.slice
            self.form = ReservationChangeForm
        else:
            if getattr(request, "_refresh", False):
                self.form = ReservationAddRefreshForm
            else:
                self.form = ReservationAddForm
        return super(ReservationAdmin, self).get_form(request, obj, **kwargs)

    def get_readonly_fields(self, request, obj=None):
        if (obj is not None):
            # Prevent slice from being changed after the reservation has been
            # created.
            return ['slice']
        else:
            return []

    def queryset(self, request):
        return Reservation.select_by_user(request.user)

class NetworkParameterTypeAdmin(PlanetStackBaseAdmin):
    list_display = ("backend_status_icon", "name", )
    list_display_links = ('backend_status_icon', 'name', )
    user_readonly_fields = ['name']
    user_readonly_inlines = []

class RouterAdmin(PlanetStackBaseAdmin):
    list_display = ("backend_status_icon", "name", )
    list_display_links = ('backend_status_icon', 'name', )
    user_readonly_fields = ['name']
    user_readonly_inlines = []

class RouterInline(PlStackTabularInline):
    model = Router.networks.through
    extra = 0
    verbose_name_plural = "Routers"
    verbose_name = "Router"
    suit_classes = 'suit-tab suit-tab-routers'

class NetworkParameterInline(PlStackGenericTabularInline):
    model = NetworkParameter
    extra = 0
    verbose_name_plural = "Parameters"
    verbose_name = "Parameter"
    suit_classes = 'suit-tab suit-tab-netparams'
    fields = ['backend_status_icon', 'parameter', 'value']
    readonly_fields = ('backend_status_icon', )

class NetworkSliversInline(PlStackTabularInline):
    fields = ['backend_status_icon', 'network','sliver','ip']
    readonly_fields = ("backend_status_icon", "ip", )
    model = NetworkSliver
    selflink_fieldname = "sliver"
    extra = 0
    verbose_name_plural = "Slivers"
    verbose_name = "Sliver"
    suit_classes = 'suit-tab suit-tab-networkslivers'

class NetworkSlicesInline(PlStackTabularInline):
    model = NetworkSlice
    selflink_fieldname = "slice"
    extra = 0
    verbose_name_plural = "Slices"
    verbose_name = "Slice"
    suit_classes = 'suit-tab suit-tab-networkslices'
    fields = ['backend_status_icon', 'network','slice']
    readonly_fields = ('backend_status_icon', )

class NetworkDeploymentsInline(PlStackTabularInline):
    model = NetworkDeployments
    extra = 0
    verbose_name_plural = "Network Deployments"
    verbose_name = "Network Deployment"
    suit_classes = 'suit-tab suit-tab-admin-only'
    fields = ['backend_status_icon', 'deployment','net_id','subnet_id']
    readonly_fields = ('backend_status_icon', )

class NetworkAdmin(PlanetStackBaseAdmin):
    list_display = ("backend_status_icon", "name", "subnet", "ports", "labels")
    list_display_links = ('backend_status_icon', 'name', )
    readonly_fields = ("subnet", )

    inlines = [NetworkParameterInline, NetworkSliversInline, NetworkSlicesInline, RouterInline]
    admin_inlines = [NetworkDeploymentsInline]

    fieldsets = [
        (None, {'fields': ['backend_status_text', 'name','template','ports','labels','owner','guaranteedBandwidth', 'permitAllSlices','permittedSlices','network_id','router_id','subnet_id','subnet'], 'classes':['suit-tab suit-tab-general']}),]

    readonly_fields = ('backend_status_text', )
    user_readonly_fields = ['name','template','ports','labels','owner','guaranteedBandwidth', 'permitAllSlices','permittedSlices','network_id','router_id','subnet_id','subnet']

    @property
    def suit_form_tabs(self):
        tabs=[('general','Network Details'),
            ('netparams', 'Parameters'),
            ('networkslivers','Slivers'),
            ('networkslices','Slices'),
            ('routers','Routers'),
        ]

        request=getattr(_thread_locals, "request", None)
        if request and request.user.is_admin:
            tabs.append( ('admin-only', 'Admin-Only') )

        return tabs


class NetworkTemplateAdmin(PlanetStackBaseAdmin):
    list_display = ("backend_status_icon", "name", "guaranteedBandwidth", "visibility")
    list_display_links = ('backend_status_icon', 'name', )
    user_readonly_fields = ["name", "guaranteedBandwidth", "visibility"]
    user_readonly_inlines = []

class FlavorAdmin(PlanetStackBaseAdmin):
    list_display = ("backend_status_icon", "name", "flavor", "order", "default")
    list_display_links = ("backend_status_icon", "name")
    user_readonly_fields = ("name", "flavor")
    fields = ("name", "description", "flavor", "order", "default")

# register a signal that caches the user's credentials when they log in
def cache_credentials(sender, user, request, **kwds):
    auth = {'username': request.POST['username'],
            'password': request.POST['password']}
    request.session['auth'] = auth
user_logged_in.connect(cache_credentials)

def dollar_field(fieldName, short_description):
    def newFunc(self, obj):
        try:
            x= "$ %0.2f" % float(getattr(obj, fieldName, 0.0))
        except:
            x=getattr(obj, fieldName, 0.0)
        return x
    newFunc.short_description = short_description
    return newFunc

def right_dollar_field(fieldName, short_description):
    def newFunc(self, obj):
        try:
            #x= '<div align=right style="width:6em">$ %0.2f</div>' % float(getattr(obj, fieldName, 0.0))
            x= '<div align=right>$ %0.2f</div>' % float(getattr(obj, fieldName, 0.0))
        except:
            x=getattr(obj, fieldName, 0.0)
        return x
    newFunc.short_description = short_description
    newFunc.allow_tags = True
    return newFunc

class InvoiceChargeInline(PlStackTabularInline):
    model = Charge
    extra = 0
    verbose_name_plural = "Charges"
    verbose_name = "Charge"
    exclude = ['account']
    fields = ["date", "kind", "state", "object", "coreHours", "dollar_amount", "slice"]
    readonly_fields = ["date", "kind", "state", "object", "coreHours", "dollar_amount", "slice"]
    can_delete = False
    max_num = 0

    dollar_amount = right_dollar_field("amount", "Amount")

class InvoiceAdmin(admin.ModelAdmin):
    list_display = ("date", "account")

    inlines = [InvoiceChargeInline]

    fields = ["date", "account", "dollar_amount"]
    readonly_fields = ["date", "account", "dollar_amount"]

    dollar_amount = dollar_field("amount", "Amount")

class InvoiceInline(PlStackTabularInline):
    model = Invoice
    extra = 0
    verbose_name_plural = "Invoices"
    verbose_name = "Invoice"
    fields = ["date", "dollar_amount"]
    readonly_fields = ["date", "dollar_amount"]
    suit_classes = 'suit-tab suit-tab-accountinvoice'
    can_delete=False
    max_num=0

    dollar_amount = right_dollar_field("amount", "Amount")

class PendingChargeInline(PlStackTabularInline):
    model = Charge
    extra = 0
    verbose_name_plural = "Charges"
    verbose_name = "Charge"
    exclude = ["invoice"]
    fields = ["date", "kind", "state", "object", "coreHours", "dollar_amount", "slice"]
    readonly_fields = ["date", "kind", "state", "object", "coreHours", "dollar_amount", "slice"]
    suit_classes = 'suit-tab suit-tab-accountpendingcharges'
    can_delete=False
    max_num=0

    def queryset(self, request):
        qs = super(PendingChargeInline, self).queryset(request)
        qs = qs.filter(state="pending")
        return qs

    dollar_amount = right_dollar_field("amount", "Amount")

class PaymentInline(PlStackTabularInline):
    model=Payment
    extra = 1
    verbose_name_plural = "Payments"
    verbose_name = "Payment"
    fields = ["date", "dollar_amount"]
    readonly_fields = ["date", "dollar_amount"]
    suit_classes = 'suit-tab suit-tab-accountpayments'
    can_delete=False
    max_num=0

    dollar_amount = right_dollar_field("amount", "Amount")

class AccountAdmin(admin.ModelAdmin):
    list_display = ("site", "balance_due")

    inlines = [InvoiceInline, PaymentInline, PendingChargeInline]

    fieldsets = [
        (None, {'fields': ['site', 'dollar_balance_due', 'dollar_total_invoices', 'dollar_total_payments'],'classes':['suit-tab suit-tab-general']}),]

    readonly_fields = ['site', 'dollar_balance_due', 'dollar_total_invoices', 'dollar_total_payments']

    suit_form_tabs =(
        ('general','Account Details'),
        ('accountinvoice', 'Invoices'),
        ('accountpayments', 'Payments'),
        ('accountpendingcharges','Pending Charges'),
    )

    dollar_balance_due = dollar_field("balance_due", "Balance Due")
    dollar_total_invoices = dollar_field("total_invoices", "Total Invoices")
    dollar_total_payments = dollar_field("total_payments", "Total Payments")

# Now register the new UserAdmin...
admin.site.register(User, UserAdmin)
# ... and, since we're not using Django's builtin permissions,
# unregister the Group model from admin.
#admin.site.unregister(Group)

#Do not show django evolution in the admin interface
from django_evolution.models import Version, Evolution
#admin.site.unregister(Version)
#admin.site.unregister(Evolution)


# When debugging it is often easier to see all the classes, but for regular use 
# only the top-levels should be displayed
showAll = False

admin.site.register(Deployment, DeploymentAdmin)
admin.site.register(Site, SiteAdmin)
admin.site.register(Slice, SliceAdmin)
admin.site.register(Service, ServiceAdmin)
admin.site.register(Reservation, ReservationAdmin)
admin.site.register(Network, NetworkAdmin)
admin.site.register(Router, RouterAdmin)
admin.site.register(NetworkTemplate, NetworkTemplateAdmin)
admin.site.register(Account, AccountAdmin)
admin.site.register(Invoice, InvoiceAdmin)

if True:
    admin.site.register(NetworkParameterType, NetworkParameterTypeAdmin)
    admin.site.register(ServiceClass, ServiceClassAdmin)
    #admin.site.register(PlanetStack)
    admin.site.register(Tag, TagAdmin)
    admin.site.register(DeploymentRole)
    admin.site.register(SiteRole)
    admin.site.register(SliceRole)
    admin.site.register(PlanetStackRole)
    admin.site.register(Node, NodeAdmin)
    #admin.site.register(SlicePrivilege, SlicePrivilegeAdmin)
    #admin.site.register(SitePrivilege, SitePrivilegeAdmin)
    admin.site.register(Sliver, SliverAdmin)
    admin.site.register(Image, ImageAdmin)
    admin.site.register(DashboardView, DashboardViewAdmin)
    admin.site.register(Flavor, FlavorAdmin)

