import os
import re

from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.core.urlresolvers import reverse
from django.template import Context, loader
import django.forms as forms

#from tinymce.widgets import TinyMCE

from troggle.helper import login_required_if_public
from troggle.flatpages.models import Redirect, EntranceRedirect
from troggle.core.models_caves import Cave
import troggle.core.views_caves
import troggle.settings as settings

def flatpage(request, path):
    try:
        r = Redirect.objects.get(originalURL = path)
        return HttpResponseRedirect(r.newURL) # Redirect after POST
    except Redirect.DoesNotExist:
        pass

    try:
        r = Cave.objects.get(url = path)
        return troggle.core.views_caves.caveSlug(request, r.slug())
    except Cave.DoesNotExist:
        pass
    except:
        print(" ! FAILED to get only one cave per slug for: "+path)
        caves = Cave.objects.all().filter(url = path)
        for c in caves:
            print(path, c.slug())
            if c.slug() != None:
                return troggle.core.views_caves.caveSlug(request, c.slug())
        pass

    try:
        r = EntranceRedirect.objects.get(originalURL = path)
        return troggle.core.views_caves.entranceSlug(request, r.entrance.slug())
    except EntranceRedirect.DoesNotExist:
        pass


    if path.startswith("noinfo") and settings.PUBLIC_SITE and not request.user.is_authenticated():
        print(("flat path noinfo", path))
        return HttpResponseRedirect(reverse("auth_login") + '?next=%s' % request.path)

    if path.endswith("/") or path == "":
        try:
            o = open(os.path.normpath(settings.EXPOWEB + path + "index.html"), "rb")
            path = path + "index.html"
        except IOError:
            try:
                o = open(os.path.normpath(settings.EXPOWEB + path + "index.htm"), "rb")
                path = path + "index.htm"
            except IOError:
                return render(request, 'pagenotfound.html', {'path': path})
    else:        
        try:
            filetobeopened = os.path.normpath(settings.EXPOWEB + path)
            o = open(filetobeopened, "rb")
        except IOError:
            return render(request, 'pagenotfound.html', {'path': path})
    if path.endswith(".htm") or path.endswith(".html"):
        html = o.read()
        
        m = re.search(rb'(.*)<\s*head([^>]*)>(.*)<\s*/head\s*>(.*)<\s*body([^>]*)>(.*)<\s*/body\s*>(.*)', html, re.DOTALL + re.IGNORECASE)
        if m:
            preheader, headerattrs, head, postheader, bodyattrs, body, postbody = m.groups()
        else:
            return HttpResponse(html + "Page could not be split into header and body")
        m = re.search(rb"<title>(.*)</title>", head, re.DOTALL + re.IGNORECASE)
        if m:
            title, = m.groups()
        else:
            title = ""
        m = re.search(rb"<meta([^>]*)noedit", head, re.DOTALL + re.IGNORECASE)
        if m:
            editable = False
        else:
            editable = True
        
        has_menu = False
        menumatch = re.match(rb'(.*)<div id="menu">', body, re.DOTALL + re.IGNORECASE)
        if menumatch:
            has_menu = True
        menumatch = re.match(rb'(.*)<ul id="links">', body, re.DOTALL + re.IGNORECASE)
        if menumatch:
            has_menu = True
            #body, = menumatch.groups()
        if re.search(rb"iso-8859-1", html):
            body = str(body, "iso-8859-1")
            body.strip
        return render(request, 'flatpage.html', {'editable': editable, 'path': path, 'title': title, 'body': body, 'homepage': (path == "index.htm"), 'has_menu': has_menu})
    else:
        return HttpResponse(o.read(), content_type=getmimetype(path))

def getmimetype(path):
    if path.lower().endswith(".png"): return "image/png"
    if path.lower().endswith(".tif"): return "image/tif"
    if path.lower().endswith(".gif"): return "image/gif"
    if path.lower().endswith(".jpeg"): return "image/jpeg"
    if path.lower().endswith(".jpg"): return "image/jpeg"
    if path.lower().endswith("svg"): return "image/svg+xml"
    if path.lower().endswith(".pdf"): return "application/pdf"
    if path.lower().endswith(".ps"): return "application/postscript"
    if path.lower().endswith(".svx"): return "application/x-survex-svx"
    if path.lower().endswith(".3d"): return "application/x-survex-3d"
    if path.lower().endswith(".pos"): return "application/x-survex-pos"
    if path.lower().endswith(".err"): return "application/x-survex-err"
    if path.lower().endswith(".odt"): return "application/vnd.oasis.opendocument.text"
    if path.lower().endswith(".ods"): return "application/vnd.oasis.opendocument.spreadsheet"
    return ""

@login_required_if_public
def editflatpage(request, path):
    try:
        r = Cave.objects.get(url = path)
        return troggle.core.views_caves.editCave(request, r.cave.slug)
    except Cave.DoesNotExist:
        pass


    try:
        filepath = os.path.normpath(settings.EXPOWEB + path)
        o = open(filepath, "r")
        html = o.read()
        autogeneratedmatch = re.search(r"\<\!--\s*(.*?(Do not edit|auto-generated).*?)\s*--\>", html, re.DOTALL + re.IGNORECASE)
        if autogeneratedmatch:
            return HttpResponse(autogeneratedmatch.group(1))
        m = re.search(r"(.*)<head([^>]*)>(.*)</head>(.*)<body([^>]*)>(.*)</body>(.*)", html, re.DOTALL + re.IGNORECASE)
        if m:
            filefound = True
            preheader, headerargs, head, postheader, bodyargs, body, postbody = m.groups()
            linksmatch = re.match(r'(.*)(<ul\s+id="links">.*)', body, re.DOTALL + re.IGNORECASE)
            if linksmatch:
                body, links = linksmatch.groups()
            if re.search(r"iso-8859-1", html):
                body = str(body, "iso-8859-1")
        else:
            return HttpResponse("Page could not be split into header and body")
    except IOError:
        filefound = False
        

    if request.method == 'POST': # If the form has been submitted...
        flatpageForm = FlatPageForm(request.POST) # A form bound to the POST data
        if flatpageForm.is_valid():# Form valid therefore write file
            if filefound:
                headmatch =  re.match(r"(.*)<title>.*</title>(.*)", head, re.DOTALL + re.IGNORECASE)
                if headmatch:
                    head = headmatch.group(1) + "<title>" + flatpageForm.cleaned_data["title"] + "</title>" + headmatch.group(2)
                else:
                    head = "<title>" + flatpageForm.cleaned_data["title"] + "</title>"
            else:
                head = "<title>" + flatpageForm.cleaned_data["title"] + "</title>"
                preheader = "<html>"
                headerargs = ""
                postheader = ""
                bodyargs = ""
                postbody = "</html>" 
            body = flatpageForm.cleaned_data["html"]
            body = body.replace("\r", "")
            result = "%s<head%s>%s</head>%s<body%s>\n%s</body>%s" % (preheader, headerargs, head, postheader, bodyargs, body, postbody)
            f = open(filepath, "w")
            f.write(result)
            f.close()
            return HttpResponseRedirect(reverse('flatpage', args=[path])) # Redirect after POST
    else:
        if filefound:
            m = re.search(r"<title>(.*)</title>", head, re.DOTALL + re.IGNORECASE)
            if m: 
                title, = m.groups()
            else:
                title = ""
            flatpageForm = FlatPageForm({"html": body, "title": title})
        else:
            flatpageForm = FlatPageForm()
    return render(request, 'editflatpage.html', {'path': path, 'form': flatpageForm, })

class FlatPageForm(forms.Form):
    title = forms.CharField(widget=forms.TextInput(attrs={'size':'60'}))

    #html = forms.CharField(widget=TinyMCE(attrs={'cols': 80, 'rows': 20}))
    html = forms.CharField(widget=forms.Textarea(attrs={"cols":80, "rows":20}))