from django.views.generic import DetailView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.decorators.http import require_GET, require_POST
from django.http import HttpResponseForbidden, HttpResponse
from django.conf import settings
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import get_object_or_404
from django.db import models
from django.db.models.functions import Concat

from djadhere.utils import get_active_filter
from djadhere.decorators import api_key_required
from .models import Service, Route, IPResource, ServiceAllocation
from .utils.fastpinger import fastpinger_update
from .utils.architecture import export_switch, export_ip


class ServiceDetail(LoginRequiredMixin, DetailView):
    def get_queryset(self):
        adhesions = self.request.user.profile.adhesions.values_list('pk')
        return Service.objects.filter(adhesion__pk__in=adhesions).order_by('service_type')


@csrf_exempt
@require_POST
def fastpinger(request):
    if request.POST.get('key', None) != settings.FASTPINGER_KEY:
        return HttpResponseForbidden('Invalid key.')
    if 'fastpinger' not in request.FILES:
        return HttpResponse(status=400)  # Bad Request
    stats = fastpinger_update(request.FILES['fastpinger'])
    return HttpResponse(stats + '\n')


@require_GET
@api_key_required
def routes(request, route=None):
    resources = IPResource.objects.filter(category=IPResource.CATEGORY_PUBLIC)
    if route:
        route = get_object_or_404(Route, name=route)
        resources = resources.filter(pk__in=route.get_ip())
    resources = resources.annotate(
            route=models.Subquery(
                ServiceAllocation.objects.filter(
                    models.Q(resource=models.OuterRef('pk')) & get_active_filter(),
                ).values('route__name')[:1],
            )
    )
    resources = resources.annotate(
            route=models.Case(
                models.When(reserved=True, then=models.Value('reserved')),
                models.When(route__isnull=True, then=models.Value('unused')),
                default='route',
                output_field=models.CharField()
            )
    )
    resources = resources.annotate(
            route=Concat('ip', models.Value(' '), 'route', output_field=models.CharField()),
    )
    resources = resources.annotate(
            order=models.Case(
                models.When(ip__startswith='91.224', then=1),
                models.When(ip__startswith='89.234', then=2),
                models.When(ip__startswith='185.119', then=3),
            )
    )
    resources = resources.order_by('order', 'ip')
    content = '\n'.join(resources.values_list('route', flat=True)) + '\n'
    return HttpResponse(content, content_type='text/plain; charset=utf-8')


@require_GET
@api_key_required
def architecture_switch(request):
    return HttpResponse(export_switch(), content_type='text/plain; charset=utf-8')


@require_GET
@api_key_required
def architecture_ip(request):
    return HttpResponse(export_ip(), content_type='text/plain; charset=utf-8')