import urllib3
from django.contrib.auth.decorators import permission_required
from django.core.exceptions import ValidationError
from django.db import transaction
from django.shortcuts import get_object_or_404

from common.decorators import ajax
from shellvalier import settings
from unifier.models import UnifiedFrame, UnifiedFrame2SlowalFrameMapping, UnifiedFrameArgumentSlowalFrameMapping
from users.models import Assignment

from . import choices
from .models import Frame


@ajax(login_required=True, method='post')
@transaction.atomic
def frame_mark_as_invalid(request, frame_pk):
    frame = get_object_or_404(Frame.objects.filter(status=choices.FrameStatus.NEW).select_for_update(), pk=frame_pk)
    frame.status = choices.FrameStatus.INVALID
    frame.save()
    return {}


@ajax(login_required=True, method='post')
@transaction.atomic
@permission_required('semantics.manage_invalid_lexical_units')
def frame_confirm_invalid(request, frame_pk):
    frame = get_object_or_404(Frame.objects.filter(status=choices.FrameStatus.INVALID).select_for_update(), pk=frame_pk)
    frame.status = choices.FrameStatus.BAD
    frame.save()
    removeSlovalFrameMappingsAndAssigments(frame_pk)

    http = urllib3.PoolManager()
    r = http.request('GET', settings.SLOWAL_FRAME_REMOVE_SERVICE_URL + str(frame_pk) +
                     settings.SLOWAL_FRAME_SERVICE_SYSTEM_TYPE_ARG)

    return {}


@ajax(login_required=True, method='post')
@transaction.atomic
@permission_required('semantics.manage_invalid_lexical_units')
def frame_reject_invalid(request, frame_pk):
    frame = get_object_or_404(Frame.objects.filter(status=choices.FrameStatus.INVALID).select_for_update(), pk=frame_pk)
    frame.status = choices.FrameStatus.NEW
    frame.save()
    removeSlovalFrameMappingsAndAssigments(frame_pk)

    http = urllib3.PoolManager()
    r = http.request('GET', settings.SLOWAL_FRAME_REMOVE_SERVICE_URL + str(frame_pk) +
                     settings.SLOWAL_FRAME_SERVICE_SYSTEM_TYPE_ARG)

    return {}


@ajax(login_required=True, method='post')
@transaction.atomic
@permission_required('semantics.manage_invalid_lexical_units')
def frame_mark_as_bad(request, frame_pk):
    frame = get_object_or_404(Frame.objects.filter(status=choices.FrameStatus.NEW).select_for_update(), pk=frame_pk)
    frame.status = choices.FrameStatus.BAD
    frame.save()
    removeSlovalFrameMappingsAndAssigments(frame_pk)

    http = urllib3.PoolManager()
    r = http.request('GET', settings.SLOWAL_FRAME_REMOVE_SERVICE_URL + str(frame_pk) +
                     settings.SLOWAL_FRAME_SERVICE_SYSTEM_TYPE_ARG)

    return {}


def removeSlovalFrameMappingsAndAssigments(frame_pk):
    #odpianie z ramy zunifikowanej
    unified_frame2_slowal_frame_mappings = UnifiedFrame2SlowalFrameMapping.objects.filter(slowal_frame_id=frame_pk)
    for unified_frame2_slowal_frame_mapping in unified_frame2_slowal_frame_mappings:
        unified_frame_argument_slowal_frame_mappings = UnifiedFrameArgumentSlowalFrameMapping.objects.filter(unified_frame_mapping=unified_frame2_slowal_frame_mapping)
        for unified_frame_argument_slowal_frame_mapping in unified_frame_argument_slowal_frame_mappings:
            unified_frame_argument_slowal_frame_mapping.delete()
        unified_frame2_slowal_frame_mapping.delete()
    Assignment.delete(subject_id=frame_pk)


@ajax(login_required=True, method='post')
@transaction.atomic
@permission_required('semantics.manage_invalid_lexical_units')
def frame_reject_as_not_matching_unified_frame(request, frame_pk):
    frame = get_object_or_404(Frame.objects.filter(status=choices.FrameStatus.NOT_MATCHING_UNIFIED_FRAME).select_for_update(), pk=frame_pk)
    frame.status = choices.FrameStatus.PROCESSING
    frame.save()
    return {}


@ajax(login_required=True, method='post')
@transaction.atomic
@permission_required('semantics.manage_invalid_lexical_units')
def frame_confirm_as_not_matching_unified_frame(request, frame_pk):
    frame = get_object_or_404(Frame.objects.filter(status=choices.FrameStatus.NOT_MATCHING_UNIFIED_FRAME).select_for_update(), pk=frame_pk)
    frame.status = choices.FrameStatus.NEW
    frame.save()
    removeSlovalFrameMappingsAndAssigments(frame_pk)

    http = urllib3.PoolManager()
    r = http.request('GET', settings.SLOWAL_FRAME_REMOVE_SERVICE_URL + str(frame_pk) +
                     settings.SLOWAL_FRAME_SERVICE_SYSTEM_TYPE_ARG)

    return {}