# -*- coding: utf8 -*-
# This file is part of k4ever, a point-of-sale system
#   Contact............  <k4ever@lists.someserver.de>
#   Website............  http://k4ever.someserver.de/
#   Bug tracker........  http://k4ever.someserver.de/report
#
# Licensed under GNU Affero General Public License v3 or later

from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth.decorators import login_required
from django.db.models import Count, Max
from django.http import HttpResponseRedirect
from django.shortcuts import render_to_response
from django.template import RequestContext

from buyable.models import Purchase, Buyable, BuyableType
from main.helper import getUserFromAuthblob
from main.models import Plugin, PluginPermission
from settings import SNACK_TYPE_ID, DRINK_TYPE_ID

@login_required
def startpage(request):
	''' Diese Funktion wird wahrscheinlich viel Last erzeugen, da 
	sie ueber mehrere Tabellen joined,filtered und wieder reduced.
	'''
	drinks = BuyableType.objects.get(pk=DRINK_TYPE_ID).buyable_set.all()
	snacks = BuyableType.objects.get(pk=SNACK_TYPE_ID).buyable_set.all()

	context = {}

	drink_data = (drinks, ('allMostDrinks', 'usersMostDrinks', 'usersLastDrinks'))
	snack_data = (snacks, ('allMostSnacks', 'usersMostSnacks', 'usersLastSnacks'))

	for buyables, context_vars in (drink_data, snack_data):
		buyables = buyables.values('name', 'id','image','price','deposit')

		# allMost
		context[context_vars[0]] = buyables.filter(purchase__isDeposit=False).annotate(
				num_buys=Count('purchase')).order_by('-num_buys')[:5]

		# filtert fuer die anderen Variablen vor
		buyables = buyables.filter( purchase__order__user=request.user.id,
									purchase__isDeposit=False)
		buyables = buyables.annotate(num_buys=Count('purchase'))

		# usersMost
		context[context_vars[1]] = buyables.order_by('-num_buys')[:5]

		# usersLast
		buyables = buyables.annotate(max_dateTime=Max('purchase__order__dateTime'))
		context[context_vars[2]] = buyables.order_by('-max_dateTime')[:5]

	return render_to_response("main/startpage.html", context, RequestContext(request))


def register(request):
	""" The "no registration available" page... """
	return render_to_response("registration/register.html", RequestContext(request))


def getPluginDict(request):
	""" Generate a dict containing the users plugin information. """
	plugins = Plugin.objects.all()
	allowed = Plugin.objects.filter(pluginpermission__user=request.user)
	unallowed = Plugin.objects.exclude(pluginpermission__user=request.user)
	perms = PluginPermission.objects.filter(user=request.user)
	
	form = None
	if request.user.has_usable_password():
		form = PasswordChangeForm(request.user)
	
	return {'plugins': plugins, 'allowed': allowed, 'unallowed': unallowed, 'permissions': perms, 'form': form}

@login_required
def settings(request):
	""" Render settings page. """
	pdict = getPluginDict(request)
	if request.method == "POST":
		form = PasswordChangeForm(request.user, data=request.POST)
		if form.is_valid():
			form.save()
			pdict['password_success'] = "Es wurde ein neues Passwort gesetzt."
		pdict['form'] = form
	return render_to_response("settings/settings.html", pdict, RequestContext(request))

@login_required
def pluginPermission(request, method, pluginId):
	""" View to edit the users :class:`Plugin` permissions. """
	plugin = None
	try:
		plugin = Plugin.objects.get(id=pluginId)
	except Plugin.DoesNotExist:
		d = getPluginDict(request)
		d['pluginerror'] = "Ein Plugin mit der angegebenen ID existiert nicht"
		return render_to_response("settings/settings.html", d, RequestContext(request))
	
	if method == "allow":
		try:
			p = PluginPermission.objects.get(user=request.user, plugin=plugin)
			d = getPluginDict(request)
			d['pluginerror'] = "Dieses Plugin wurde bereits erlaubt"
			return render_to_response("settings/settings.html", d, RequestContext(request))
		except PluginPermission.DoesNotExist:
			p = PluginPermission(user=request.user, plugin=plugin)
			p.save()
	else:
		try:
			p = PluginPermission.objects.get(user=request.user, plugin=plugin)
			p.delete()
		except PluginPermission.DoesNotExist:
			d = getPluginDict(request)
			d['pluginerror'] = "Keine Berechtigungen f&uuml;r dieses Plugin gefunden - kann also auch nicht zur&uuml;ckgezogen werden"
			return render_to_response("settings/settings.html", d, RequestContext(request))
	return HttpResponseRedirect("/user/settings/")

@login_required
def pluginAuthblob(request, pluginId):
	""" View to edit the users :attr:`authblob <PluginPermission.authblob>`. """
	if request.method != "POST":
		return HttpResponseRedirect("/user/settings/")
	
	# find plugin
	plugin = None
	try:
		plugin = Plugin.objects.get(id=pluginId)
	except Plugin.DoesNotExist:
		d = getPluginDict(request)
		d['pluginerror'] = "Ein Plugin mit der angegebenen ID existiert nicht"
		return render_to_response("settings/settings.html", d, RequestContext(request))
	
	# find plugin permission for user
	p = None
	try:
		p = PluginPermission.objects.get(user=request.user, plugin=plugin)
	except PluginPermission.DoesNotExist:
		d = getPluginDict(request)
		d['pluginerror'] = "Vor dem editieren vom Authblob muss das Plugin ersteinmal erlaubt werden"
		return render_to_response("settings/settings.html", d, RequestContext(request))
	
	# has the user write access to the authblob?
	if not p.plugin.userCanWriteAuthblob or not request.POST.has_key("authblob"):
		d = getPluginDict(request)
		d['pluginerror'] = "Der Authblob darf f&uuml;r dieses Plugin nicht vom User ver&auml;ndert werden (oder der Authblob war kaputt)"
		return render_to_response("settings/settings.html", d, RequestContext(request))
	
	# clean authblob \r\n ==> \n
	authblob = request.POST["authblob"].replace("\r\n", "\n")
	
	# is the authblob too long (too many lines)?
	if p.plugin.maxLinesPerAuthblob > 0 and (authblob.rstrip().count("\n") + 1) > p.plugin.maxLinesPerAuthblob:
		d = getPluginDict(request)
		d['pluginerror'] = "Der Authblob darf maximal %d Zeilen haben" % (p.plugin.maxLinesPerAuthblob,)
		return render_to_response("settings/settings.html", d, RequestContext(request))
	
	# check, if this is equal to the old users plugin
	pluginsWithAuthblob = PluginPermission.objects.filter(plugin=plugin, user=request.user, authblob=authblob)
	if pluginsWithAuthblob.count() > 0:
		d = getPluginDict(request)
		d['pluginerror'] = "Das ist der gleiche Authblob, den du vorher auch hattest."
		return render_to_response("settings/settings.html", d, RequestContext(request))
	
	# check for every authblob-line, if there is somebody who has it (if unique)
	if p.plugin.uniqueAuthblob:
		print authblob.split("\n")
		for line in authblob.split("\n"):
			usr = getUserFromAuthblob(line, plugin)
			if usr:
				if usr == request.user:
					# we know this one
					continue
				else:
					d = getPluginDict(request)
					d['pluginerror'] = "Achtung! Dein Authblob (bzw. eine der Zeile davon) wird bereits von einer anderen Person benutzt. Bitte w&auml;hle einen anderen (eindeutigen) Authblob!"
					return render_to_response("settings/settings.html", d, RequestContext(request))
	
	p.authblob = authblob
	p.save()
	d = getPluginDict(request)
	d['pluginmsg'] = "Authblob erfolgreich ge&auml;ndert"
	return render_to_response("settings/settings.html", d, RequestContext(request))

