from urllib.parse import urlparse

from django.forms import ModelForm
from django.http import HttpRequest, HttpResponse, HttpResponseForbidden


def same_origin(current_uri, redirect_uri):
    a = urlparse(current_uri)
    if not a.scheme:
        return True
    b = urlparse(redirect_uri)
    return (a.scheme, a.hostname, a.port) == (b.scheme, b.hostname, b.port)


def turbolinks(request: HttpRequest):
    ctx = {}
    if request.META.get('HTTP_TURBOLINKS_REFERRER') is not None:
        ctx['is_turbolinks'] = True
    return ctx


class TurbolinksMiddleware:
    def process_request(self, request: HttpRequest):
        referrer = request.META.get('HTTP_TURBOLINKS_REFERRER')
        if referrer:
            request.META['HTTP_REFERER'] = referrer
        return

    def process_response(self, request: HttpRequest, response: HttpResponse):
        referrer = request.META.get('HTTP_TURBOLINKS_REFERRER')
        if referrer is None:
            return response

        if response.has_header('Location'):
            loc = response['Location']
            request.session['_turbolinks_redirect_to'] = loc

            if referrer and not same_origin(loc, referrer):
                return HttpResponseForbidden()
        else:
            if request.session.get('_turbolinks_redirect_to'):
                loc = request.session.pop('_turbolinks_redirect_to')
                response['Turbolinks-Location'] = loc

        return response


def get_config_form(mdl):
    class ConfigForm(mdl.CONFIG_FORM_CLASS if hasattr(mdl, 'CONFIG_FORM_CLASS') else ModelForm):
        prefix = 'config'

        class Meta:
            model = mdl
            exclude = mdl.EXCLUDE_FIELDS if hasattr(mdl, 'EXCLUDE_FIELDS') else ()
            widgets = mdl.CUSTOM_WIDGETS if hasattr(mdl, 'CUSTOM_WIDGETS') else {}
    return ConfigForm
