#!/usr/bin/env python3

from django.db.models import Q

from tastypie import fields
from tastypie.authentication import Authentication
from tastypie.resources import ModelResource
from tastypie.throttle import BaseThrottle
from tastypie.constants import ALL, ALL_WITH_RELATIONS

from main.models import Movie
from main.models import Person
from main.models import Country

from django.conf import settings


class CustomAuthentication(Authentication):

    def is_authenticated(self, request, **kwargs):
        if not 'ApiToken' in request.headers:
            return False

        if request.headers['ApiToken'] != settings.API_TOKEN:
            return False

        return True


class ResourceDirectors(ModelResource):

    class Meta:
        queryset = Person.objects.all().filter(is_director=True)
        resource_name = 'directors'


class ResourceCountries(ModelResource):

    class Meta:
        queryset = Country.objects.all()
        resource_name = 'countries'


class ResourceMovies(ModelResource):
    directors = fields.ToManyField(ResourceDirectors, 'directors', full=True)
    countries = fields.ToManyField(ResourceCountries, 'countries', full=True)

    class Meta:
        queryset = Movie.objects.all().order_by('-id')
        resource_name = 'movies'
        excludes = ['count', 'duration', 'published', 'stars']
        throttle = BaseThrottle(throttle_at=50)
        allowed_methods = ['get']
        authentication = CustomAuthentication()
        limit = 10
        max_limit = 10
        filtering = {
            'name': ALL,
            'original_name': ALL,
        }

    def dehydrate_directors(self, bundle):
        names = ', '.join([d.obj.name for d in bundle.data['directors']])
        return names

    def dehydrate_countries(self, bundle):
        names = ', '.join([c.obj.name for c in bundle.data['countries']])
        return names

    # ~ def build_filters(self, filters=None, **kwargs):
        # ~ orm_filters = super().build_filters(filters or {}, **kwargs)
        # ~ return orm_filters

    def apply_filters(self, request, applicable_filters):
        objects = self.get_object_list(request)
        query = applicable_filters['name__icontains']
        qset = (Q(name__icontains=query) | Q(original_name__icontains=query))
        objects = objects.filter(qset)
        return objects
