from django.http import HttpResponseRedirect, HttpResponse
from django.shortcuts import render, get_object_or_404
from health_view.models import License, FolderInfo, Permission, FolderPart
from django.contrib.auth.models import User
from django.views import generic
from datetime import datetime
from health_view.crypto_functions import *
from health_view.forms import CreateLicenseForm
from django.contrib.auth.decorators import login_required


def index(request):
    """View function for home page of site."""
    num_licenses = License.objects.all().count()
    num_user = User.objects.all().count()
    context = {
        'num_licenses': num_licenses,
        'num_user': num_user,
    }
    return render(request, 'index.html', context=context)


class FolderInfoID(generic.ListView):
    model = FolderInfo

    def get_queryset(self):
        return FolderInfo.objects.get(patient=self.request.user)


class LicenseViewGiven(generic.ListView):
    model = License

    def get_queryset(self):
        return License.objects.filter(patient=self.request.user).order_by('patient')


class LicenseViewOwn(generic.ListView):
    model = License

    def get_queryset(self):
        return License.objects.filter(justified=self.request.user).order_by('patient')


@login_required
def get_license_details(request, pk):
    model = License
    if "own" in request.get_full_path():
        if not License.objects.filter(pk=pk, justified=request.user).exists():
            return HttpResponseRedirect('/')
        license = get_object_or_404(License, pk=pk, justified=request.user)
    if "given" in request.get_full_path():
        if not License.objects.filter(pk=pk, patient=request.user).exists():
            return HttpResponseRedirect('/')
        license = get_object_or_404(License, pk=pk, patient=request.user)
    exp_date = license.exp_date
    permission = license.permissions.all().values_list()
    permission_string = ""
    for perm in permission:
        permission_string += perm[2]
        permission_string += ", "
    folderparts_string = ""
    folderparts = license.folder_parts.all().values_list()
    for e in folderparts:
        folderparts_string += e[2]
        folderparts_string += ", "
    key = license.patient.folderinfo.content_key
    sig = license.signature
    key_split = (key[0:64], key[64:128], key[128:192], key[192:256])
    sig_split = (sig[0:64], sig[64:128], sig[128:192], sig[192:256])
    license_creator = license.license_creator
    patient = license.patient
    justified = license.justified
    if "own" in request.get_full_path():
        license_string = str(patient) + "&" + str(justified) + "&" + str(license_creator.username) + "&" + str(exp_date.replace(" ", ",") ) + "&" + get_string_byanser(permission) + "&" + get_string_byanser(folderparts) + "&" + sig + "&" + key
        server_sign = sign(license_string, priv_key_own)
        serversign_split = (server_sign[0:64], server_sign[64:128], server_sign[128:192])
    else:
        serversign_split=0
    context = {
               'patient': patient,
               'justified': justified,
               'license_creator': license_creator,
               'exp_date': exp_date,
               'permission': permission_string[:-2],
               'folderparts': folderparts_string[:-2],
               'content_key': key,
               'signature': sig_split,
               'serversign': serversign_split,
               'key_split': key_split}
    return render(request, 'health_view/license_detail.html', context)


def get_string_byrequest(index_list, model_call):
    objectstring = ""
    for i in index_list:
        objectstring += str(model_call.objects.get(id=i))
        objectstring += ","
    return objectstring[:-1]


def check_expiration_date(license):
    exp_date = license.exp_date
    datetime_object = ""
    for fmt in ('%d/%m/%Y %H:%M', '%d-%m-%Y %H:%M', '%d/%m/%Y'):
        try:
            datetime_object = datetime.strptime(exp_date, fmt)
        except ValueError:
            pass
    try:
        return datetime.now() < datetime_object
    except Exception:
        return False


def get_string_byanser(model_call):
    objectstring = ""
    for i in model_call:
        objectstring += str(i[2])
        objectstring += ","
    print(objectstring)
    return objectstring[:-1]


@login_required
def create_license(request, fid):
    model = License
    user = get_object_or_404(User, id=fid)
    if request.method == 'POST':
        post = request.POST.copy()  # to make it mutable
        pubkey = request.user.folderinfo.pub_key
        patient = User.objects.get(id=post['patient'])
        justified = User.objects.get(id=post['justified'])
        license_creator = request.user
        exp_date = post['exp_date']
        permission_ground = request.POST.getlist("permissions")
        folderparts_ground = request.POST.getlist("folder_parts")
        permission = get_string_byrequest(permission_ground, Permission)
        folderparts = get_string_byrequest(folderparts_ground, FolderPart)
        signature_string = str(patient) + "&" + str(justified) + "&" + str(license_creator.username) + "&" + str(exp_date.replace(" ", ",")) + "&" + permission + "&" + folderparts
        signature = post['signature']
        new_folder = False
        if not verify(signature_string, signature, pubkey):
            form = CreateLicenseForm(request.user)
            context = {'form': form}
            return render(request, 'health_view/create_license.html', context)
        if request.user.folderinfo.content_key == "no_key":
            request.user.folderinfo.content_key = make_encrypted_key_content_server()
            request.user.folderinfo.save()
            new_folder = True
        new_license = License(patient=patient, justified=justified, exp_date=exp_date, license_creator=license_creator, signature=signature)
        new_license.save()
        for e in permission_ground:
            new_license.permissions.add(Permission.objects.get(id=e))
        for i in folderparts_ground:
            new_license.folder_parts.add(FolderPart.objects.get(id=i))
        new_license.save()
        request.POST = post
        key = request.user.folderinfo.content_key
        key_split = (key[0:64], key[64:128], key[128:192], key[192:256])
        sig_split = (signature[0:64], signature[64:128], signature[128:192], signature[192:256])
        license_string = signature_string + "&" + new_license.signature + "&" + key
        serversign = sign(license_string, priv_key_own)
        serversign_split = (serversign[0:64], serversign[64:128], serversign[128:192])
        context = {
                   'patient': patient,
                   'justified': justified,
                   'license_creator': license_creator,
                   'exp_date': exp_date,
                   'permission': permission,
                   'folderparts': folderparts,
                   'content_key': key,
                   'signature': sig_split,
                   'key_split': key_split,
                   'serversign': serversign_split,
                   'new_folder': new_folder}
        return render(request, 'health_view/license_detail.html', context)
    else:
        form = CreateLicenseForm(request.user)
        context = {'form': form}
        return render(request, 'health_view/create_license.html', context)


def delete_license(request):
    print("test")
