from django.contrib import admin
from django.conf import settings

from pgweb.core.models import ModerationNotification
from mailqueue.util import send_simple_mail


class PgwebAdmin(admin.ModelAdmin):
	"""
	ModelAdmin wrapper that will enable a few pg specific things:
	* Markdown preview for markdown capable textfields (specified by
	  including them in a class variable named markdown_capable that is a tuple
	  of field names)
	* Add an admin field for "notification", that can be sent to the submitter
	  of an item to inform them of moderation issues.
	"""

	change_form_template = 'admin/change_form_pgweb.html'

	def formfield_for_dbfield(self, db_field, **kwargs):
		fld = admin.ModelAdmin.formfield_for_dbfield(self, db_field, **kwargs)

		if hasattr(self.model, 'markdown_fields'):
			if db_field.name in self.model.markdown_fields:
				fld.widget.attrs['class'] = fld.widget.attrs['class'] + ' markdown_preview'
		return fld

	def change_view(self, request, object_id, form_url='', extra_context=None):
		if self.model.send_notification:
			# Anything that sends notification supports manual notifications
			if extra_context == None:
				extra_context = dict()
			extra_context['notifications'] = ModerationNotification.objects.filter(objecttype=self.model.__name__, objectid=object_id).order_by('date')

		return super(PgwebAdmin, self).change_view(request, object_id, form_url, extra_context)

	# Remove the builtin delete_selected action, so it doesn't
	# conflict with the custom one.
	def get_actions(self, request):
		actions = super(PgwebAdmin, self).get_actions(request)
		del actions['delete_selected']
		return actions

	# Define a custom delete_selected action. This is required because the
	# default one uses the delete functionality in QuerySet, which bypasses
	# the delete() operation on the model, and thus won't send out our
	# notifications. Manually calling delete() on each one will be slightly
	# slower, but will send proper notifications - and it's not like this
	# is something that happens often enough that we care about performance.
	def custom_delete_selected(self, request, queryset):
		for x in queryset:
			x.delete()
	custom_delete_selected.short_description = "Delete selected items"
	actions=['custom_delete_selected']

	def save_model(self, request, obj, form, change):
		if change and self.model.send_notification:
			# We only do processing if something changed, not when adding
			# a new object.
			if request.POST.has_key('new_notification') and request.POST['new_notification']:
				# Need to send off a new notification. We'll also store
				# it in the database for future reference, of course.
				if not obj.org.email:
					# Should not happen because we remove the form field. Thus
					# a hard exception is ok.
					raise Exception("Organization does not have an email, canot send notification!")
				n = ModerationNotification()
				n.objecttype = obj.__class__.__name__
				n.objectid = obj.id
				n.text = request.POST['new_notification']
				n.author = request.user.username
				n.save()

				# Now send an email too
				msgstr = _get_notification_text(request.POST.has_key('remove_after_notify'),
												obj,
												request.POST['new_notification'])

				send_simple_mail(settings.NOTIFICATION_FROM,
								 obj.org.email,
								 "postgresql.org moderation notification",
								 msgstr)

				# Also generate a mail to the moderators
				send_simple_mail(settings.NOTIFICATION_FROM,
								 settings.NOTIFICATION_EMAIL,
								 "Moderation comment on %s %s" % (obj.__class__._meta.verbose_name, obj.id),
								 _get_moderator_notification_text(request.POST.has_key('remove_after_notify'),
																  obj,
																  request.POST['new_notification'],
																  request.user.username
															  ))

				if request.POST.has_key('remove_after_notify'):
					# Object should not be saved, it should be deleted
					obj.delete()
					return


		# Either no notifications, or done with notifications
		super(PgwebAdmin, self).save_model(request, obj, form, change)


def register_pgwebadmin(model):
	admin.site.register(model, PgwebAdmin)


def _get_notification_text(remove, obj, txt):
	objtype = obj.__class__._meta.verbose_name
	if remove:
		return """You recently submitted a %s to postgresql.org.

This submission has been rejected by a moderator, with the following comment:

%s
""" % (objtype, txt)
	else:
		return """You recently submitted a %s to postgresql.org.

During moderation, this item has received comments that need to be
addressed before it can be approved. The comment given by the moderator is:

%s

Please go to https://www.postgresql.org/account/ and make any changes
request, and your submission will be re-moderated.
""" % (objtype, txt)



def _get_moderator_notification_text(remove, obj, txt, moderator):
	return """Moderator %s made a comment to a pending object:
Object type: %s
Object id: %s
Comment: %s
Delete after comment: %s
""" % (moderator,
	   obj.__class__._meta.verbose_name,
	   obj.id,
	   txt,
	   remove and "Yes" or "No",
	   )
