import os
from datetime import datetime, date, time
from django.shortcuts import render
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponseRedirect, Http404
from django.contrib.auth.decorators import login_required
from django.forms.models import inlineformset_factory
from dynastie.models import *
from dynastie.forms import *

def index(request):
    if request.user.is_authenticated():
            return HttpResponseRedirect('/blog')

    login_failed = False
    if 'login' in request.POST:
        user = authenticate(username=request.POST['login'], password=request.POST['password'])
        if user is None:
            login_failed = True
        else:
            login(request, user)
            return HttpResponseRedirect('/blog')

    c = {'auth_key': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\
             'login_failed' : login_failed}

    return render(request, 'templates/login.html', c)

def disconnect(request):
    logout(request)
    c = {'auth_key': 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA',\
             'login_failed' : False}
    return render(request, 'templates/login.html', c)

@login_required
def user(request):
    users = User.objects.all()

    c = {'users' : users}

    return render(request, 'templates/user.html', c)

@login_required
def add_user(request):
    if not request.user.is_superuser:
        return HttpResponseRedirect('/user')
 
    if request.method == 'POST': # If the form has been submitted...
        if 'add' in request.POST:
            form = UserForm(request.POST) # A form bound to the POST data
            if form.is_valid(): # All validation rules pass
                form = form.save()
                user = User.objects.get(pk=form.id)
                user.set_password(request.POST['password'])
                user.save()
            # Process the data in form.cleaned_data
            # ...
                return HttpResponseRedirect('/user') # Redirect after POST
        else:
            return HttpResponseRedirect('/user') # Redirect after POST
    else:
        form = UserForm() # An unbound form

    return render(request, 'add_user.html', {
        'form': form,
    })

@login_required
def edit_user(request, user_id):
    user = User.objects.get(pk=user_id)

    if user is None:
        raise Http404

    edited = False

    if request.method == 'POST': # If the form has been submitted...
        if int(user_id) != int(request.user.id) and (not request.user.is_superuser):
            return HttpResponseRedirect('/user/' + str(user_id))
        if 'edit' in request.POST:
            form = UserForm(request.POST, instance=user, initial={'password':''}) # A form bound to the POST data
            if form.is_valid(): # All validation rules pass
                form.save()
                if request.POST['password'] != '':
                    user.set_password(request.POST['password'])
                user.save()
                edited = True
        else:
            if 'delete' in request.POST and request.user.is_superuser:
                User.objects.get(pk=user_id).delete()
                return HttpResponseRedirect('/user')
            if 'cancel' in request.POST:
                return HttpResponseRedirect('/user')
    else:
        form = UserForm(instance=user, initial={'password':''}) # An unbound form
        
    c = {'user_to_edit' : user, 'form' : form, 'edited' : edited}

    return render(request, 'templates/edit_user.html', c)

@login_required
def category(request):
    categories = Category.objects.all()

    c = {'categories' : categories}

    return render(request, 'templates/category.html', c)

@login_required
def add_category(request):
    if not request.user.is_superuser:
        return HttpResponseRedirect('/category')
 
    if request.method == 'POST': # If the form has been submitted...
        if 'add' in request.POST:
            form = CategoryForm(request.POST) # A form bound to the POST data
            if form.is_valid(): # All validation rules pass
                form = form.save()
            # Process the data in form.cleaned_data
            # ...
                return HttpResponseRedirect('/category') # Redirect after POST
        else:
            return HttpResponseRedirect('/category') # Redirect after POST
    else:
        form = CategoryForm() # An unbound form

    return render(request, 'add_category.html', {
        'form': form,
    })

@login_required
def edit_category(request, category_id):
    category = Category.objects.get(pk=category_id)

    if category is None:
        raise Http404

    if request.method == 'POST': # If the form has been submitted...
        if 'cancel' in request.POST:
            return HttpResponseRedirect('/category')
        if 'edit' in request.POST and request.user.is_superuser:
            name = category.name
            form = CategoryForm(request.POST, instance=category) # A form bound to the POST data
            if form.is_valid(): # All validation rules pass
                if request.POST['name'] != name:
                    category.remove()
                form.save()
    else:
        form = CategoryForm(instance=category) # An unbound form

    c = {'category' : category, 'form' : form}

    return render(request, 'templates/edit_category.html', c)

@login_required
def delete_category(request, category_id):
    if not request.user.is_superuser:
        return HttpResponseRedirect('/category/' + str(category_id))

    category = Category.objects.get(pk=category_id)

    if category is None:
        raise Http404

    category.remove()
    category.delete()

    return HttpResponseRedirect('/category')

@login_required
def blog(request):
    if request.user.is_superuser:
        b = Blog.objects.all()
    else:
        b = Blog.objects.filter(writers=request.user.id)

    c = {'blogs' : b}

    return render(request, 'templates/blog.html', c)

@login_required
def add_blog(request):
    if not request.user.is_superuser:
        return HttpResponseRedirect('/blog')
 
    if request.method == 'POST': # If the form has been submitted...
        if 'add' in request.POST:
            form = BlogForm(request.POST) # A form bound to the POST data
            if form.is_valid(): # All validation rules pass
                form = form.save()
                form.create()
                return HttpResponseRedirect('/blog') # Redirect after POST
        else:
            return HttpResponseRedirect('/blog') # Redirect after POST
    else:
        form = BlogForm() # An unbound form

    return render(request, 'add_blog.html', {
        'form': form,
    })

@login_required
def view_blog(request, blog_id):
    if not request.user.is_superuser:
        b = Blog.objects.filter(id=blog_id).filter(writers=request.user.id)
    else:
        b = Blog.objects.get(pk=blog_id)

    if b is None:
        raise Http404

    posts = Post.objects.filter(blog=b).order_by('-creation_date')
    b = Blog.objects.get(pk=blog_id)
    form = BlogForm(instance=b)
    
    c = {'blog' : b, 'posts' : posts, 'form' : form}

    return render(request, 'templates/view_blog.html', c)

@login_required
def edit_blog(request, blog_id):
    if not request.user.is_superuser:
        return HttpResponseRedirect('/blog/' + str(blog_id))

    b = Blog.objects.get(pk=blog_id)

    if b is None:
        raise Http404

    if request.method == 'POST': # If the form has been submitted...
        if 'edit' in request.POST:
            form = BlogForm(request.POST, instance=b) # A form bound to the POST data
            if form.is_valid(): # All validation rules pass
                form.save()
        else:
            if 'delete' in request.POST:
                b = Blog.objects.get(pk=blog_id)
                b.delete()
                return HttpResponseRedirect('/blog')
    else:
        form = BlogForm(instance=b) # An unbound form

    posts = Post.objects.filter(blog=b).order_by('-creation_date')

    c = {'blog' : b, 'posts' : posts, 'form' : form}

    return render(request, 'templates/view_blog.html', c)

@login_required
def add_post(request, blog_id):
    if not request.user.is_superuser:
        b = Blog.objects.filter(id=blog_id).filter(writers=request.user.id)[0]
    
        if b is None:
            raise Http404

    if request.method == 'POST': # If the form has been submitted...
        if 'add' in request.POST:
            post = Post(blog=Blog.objects.get(pk=blog_id), author=User.objects.get(pk=request.user.id), creation_date=datetime.now(), modification_date=datetime.now())
            content = request.POST['content']
            # del request.POST['content']
            form = PostForm(request.POST, instance=post) # A form bound to the POST data
            if form.is_valid(): # All validation rules pass
                form = form.save()
                form.createPost(content)
            # Process the data in form.cleaned_data
            # ...
                return HttpResponseRedirect('/blog/' + blog_id) # Redirect after POST
        else:
            return HttpResponseRedirect('/blog/' + blog_id) # Redirect after POST
    else:
        form = PostForm() # An unbound form

    return render(request, 'add_post.html', {
        'form': form, 'blog_id' : blog_id
    })

@login_required
def edit_post(request, post_id):
    post = Post.objects.get(pk=post_id)

    if post is None:
        raise Http404

    title = post.title

    blog_id = post.blog.id

    if not request.user.is_superuser:
        b = Blog.objects.filter(pk=post.blog.id).filter(writers=request.user.id)[0]
    
        if b is None:
            raise Http404
    else:
        b = Blog.objects.get(pk=post.blog.id)

    if request.method == 'POST': # If the form has been submitted...
        if 'edit' in request.POST:
            post.modification_date = datetime.now()
            form = PostForm(request.POST, instance=post) # A form bound to the POST data
            if form.is_valid(): # All validation rules pass
                if title != request.POST['title']:
                    post.remove()
                    post.createPost(request.POST['content'])
                form.save()
            # Process the data in form.cleaned_data
            # ...
                return HttpResponseRedirect('/blog/' + str(blog_id)) # Redirect after POST
        else:
            if 'cancel' in request.POST:
                return HttpResponseRedirect('/blog/' + str(blog_id)) # Redirect after POST
    else:
        form = PostForm(instance=post) # An unbound form

    b.create_paths()
    filename = b.src_path + '/_post/' + str(post.pk)
    if os.path.exists(filename):
        f = open(filename, 'rb')
        content = f.read()
        f.close()
    else:
        content = 'Empty post'

    return render(request, 'edit_post.html', {
        'form': form, 'post_id' : post_id, 'content' : content,
        'blog_id' : blog_id
    })

@login_required
def delete_post(request, post_id):
    post = Post.objects.get(pk=post_id)

    if post is None:
        raise Http404

    b = Blog.objects.filter(writers=request.user.id).filter(pk=post.blog.pk)
    
    if b is None:
        raise Http404

    blog_id = post.blog.pk

    post.delete()

    return HttpResponseRedirect('/blog/' + str(blog_id))

@login_required
def generate(request, blog_id):
    if not request.user.is_superuser:
        b = Blog.objects.filter(id=blog_id).filter(writers=request.user.id)[0]
    else:
        b = Blog.objects.get(pk=blog_id)

    if b is None:
        raise Http404

    b.create_paths()
    report = b.generate()

    posts = Post.objects.filter(blog=b).order_by('-creation_date')
    b = Blog.objects.get(pk=blog_id)
    form = BlogForm(instance=b)
    
    c = {'blog' : b, 'posts' : posts, 'form' : form, 'report': report}
    
    return render(request, 'templates/generate.html', c)

@login_required
def preview(request, blog_id):
    from dynastie.generators import post

    values = {'title' : request.POST['title'], \
              'author' : request.user.first_name + ' ' + request.user.last_name, \
              'content' : request.POST['content']
              }

    if not request.user.is_superuser:
        b = Blog.objects.filter(id=blog_id).filter(writers=request.user.id)[0]
    else:
        b = Blog.objects.get(pk=blog_id)

    if b is None:
        raise Http404

    b.create_paths()

    engine = globals()['post']

    for name, obj in inspect.getmembers(engine):
        if inspect.isclass(obj) and obj.__module__.startswith("dynastie") \
                and obj.__module__.endswith("post"):
            e = obj()
            content = e.preview(b.src_path, values)
            break

    output = b.output_path
    path = output + '/preview.html'
    if os.path.exists(path):
        os.unlink(path)

    f = open(path, 'wb')
    f.write(content)
    f.close()

    c = {'content' : content}

    # return HttpResponseRedirect('http://' + b.name + '/preview.html')
    return HttpResponseRedirect('http://' + 'localhost:8080' + '/preview.html')
