from rest_framework import viewsets,filters
from rest_framework import status
from rest_framework.response import Response
from django.core.exceptions import PermissionDenied
from rest_framework.permissions import BasePermission, AllowAny

from odevzdavatko.models import Reseni
from tvorba.models import Problem, Uloha

from .models import TextNode, CastNode, UlohaVzorakNode, UlohaZadaniNode, ReseniNode
from .models import Text
import treenode.serializers as views

from treenode.permissions import AllowWrite

class PermissionMixin(object):
	""" Redefines get_permissions so that only organizers can make changes. """

	def get_permissions(self):
		permission_classes = []
		print("get_permissions have been called.")
		if self.action in ["create", "update", "partial_update", "destroy"]:
			permission_classes = [AllowWrite] # speciální permission na zápis - orgové
		else:
			permission_classes = [AllowAny] 
		# návštěvník nemusí být zalogován, aby si prohlížel obsah
		return [permission() for permission in permission_classes]

class ReadWriteSerializerMixin(object):
	"""
	Overrides get_serializer_class to choose the read serializer
	for GET requests and the write serializer for POST requests.

	Set read_serializer_class and write_serializer_class attributes on a
	viewset. 
	"""

	read_serializer_class = None
	create_serializer_class = None
	write_serializer_class = None

	def get_serializer_class(self):		
		if self.action == "create":
			return self.get_create_serializer_class()
		if self.action in ["update", "partial_update", "destroy"]:
			return self.get_write_serializer_class()
		return self.get_read_serializer_class()

	def get_read_serializer_class(self):
		assert self.read_serializer_class is not None, (
			"'%s' should either include a `read_serializer_class` attribute,"
			"or override the `get_read_serializer_class()` method."
			% self.__class__.__name__
		)
		return self.read_serializer_class

	def get_write_serializer_class(self):
		assert self.write_serializer_class is not None, (
			"'%s' should either include a `write_serializer_class` attribute,"
			"or override the `get_write_serializer_class()` method."
			% self.__class__.__name__
		)
		return self.write_serializer_class

	def get_create_serializer_class(self):
		assert self.create_serializer_class is not None, (
			"'%s' should either include a `create_serializer_class` attribute,"
			"or override the `get_create_serializer_class()` method."
			% self.__class__.__name__
		)
		return self.create_serializer_class

class TextViewSet(PermissionMixin, viewsets.ModelViewSet):
	queryset = Text.objects.all()
	serializer_class = views.TextSerializer

class TextNodeViewSet(PermissionMixin, ReadWriteSerializerMixin,viewsets.ModelViewSet):
	queryset = TextNode.objects.all()
	read_serializer_class = views.TextNodeSerializer
	write_serializer_class = views.TextNodeWriteSerializer
	create_serializer_class = views.TextNodeCreateSerializer

class CastNodeViewSet(PermissionMixin, ReadWriteSerializerMixin,viewsets.ModelViewSet):
	queryset = CastNode.objects.all()
	read_serializer_class = views.CastNodeSerializer
	write_serializer_class = views.CastNodeSerializer
	create_serializer_class = views.CastNodeCreateSerializer

	def destroy(self, request, *args, **kwargs):
		obj = self.get_object()
		print(obj)
		if obj.first_child is None:
			return super().destroy(request,*args,**kwargs)
		raise PermissionDenied('Nelze smazat CastNode, který má děti!')


class UlohaVzorakNodeViewSet(PermissionMixin, ReadWriteSerializerMixin, viewsets.ModelViewSet):
	read_serializer_class = views.UlohaVzorakNodeSerializer
	write_serializer_class = views.UlohaVzorakNodeWriteSerializer
	create_serializer_class = views.UlohaVzorakNodeCreateSerializer

	def get_queryset(self):
		queryset = UlohaVzorakNode.objects.all()
		nazev = self.request.query_params.get('nazev',None)
		if nazev is not None:
			queryset = queryset.filter(nazev__contains=nazev)

		if self.request.user.has_perm('auth.org'):
			return queryset
		else: # pro neorgy jen zveřejněné vzoráky
			return queryset.filter(uloha__cislo_reseni__verejne_db=True)

		nadproblem = self.request.query_params.get('nadproblem',None)
		if nadproblem is not None:
			queryset = queryset.filter(nadproblem__pk = nadproblem)
		return queryset

class ReseniViewSet(viewsets.ModelViewSet):
	serializer_class = views.ReseniSerializer

	def get_queryset(self):
		queryset = Reseni.objects.all()
		#FIXME upravit nazvy dle skutecnych polozek reseni
		nazev = self.request.query_params.get('nazev',None)
		if nazev is not None:
			queryset = queryset.filter(nazev__contains=nazev)
		nadproblem = self.request.query_params.get('nadproblem',None)
		if nadproblem is not None:
			queryset = queryset.filter(nadproblem__pk = nadproblem)
		return queryset

class UlohaViewSet(viewsets.ModelViewSet):
	serializer_class = views.UlohaSerializer

	def get_queryset(self):
		queryset = Uloha.objects.all()
		nazev = self.request.query_params.get('nazev',None)
		if nazev is not None:
			queryset = queryset.filter(nazev__contains=nazev)
		nadproblem = self.request.query_params.get('nadproblem',None)
		if nadproblem is not None:
			queryset = queryset.filter(nadproblem__pk = nadproblem)
		return queryset

class UlohaZadaniNodeViewSet(ReadWriteSerializerMixin, viewsets.ModelViewSet):
	queryset = UlohaZadaniNode.objects.all()
	read_serializer_class = views.UlohaZadaniNodeSerializer
	write_serializer_class = views.UlohaZadaniNodeWriteSerializer
	create_serializer_class = views.UlohaZadaniNodeCreateSerializer

class ReseniNodeViewSet(ReadWriteSerializerMixin, viewsets.ModelViewSet):
	queryset = ReseniNode.objects.all()
	read_serializer_class = views.ReseniNodeSerializer
	write_serializer_class = views.ReseniNodeWriteSerializer
	create_serializer_class = views.ReseniNodeCreateSerializer



class ProblemViewSet(viewsets.ModelViewSet):
	serializer_class = views.ProblemSerializer

	def get_queryset(self):
		queryset = Problem.objects.all()
		ucel = self.request.query_params.get('ucel',None)
		rocnik = self.request.query_params.get('rocnik',None)
		tema = self.request.query_params.get('tema',None)

		if rocnik is not None:
			queryset = queryset.filter(rocnik=rocnik)

		#if tema is not None:



		return queryset