from __future__ import division

from datetime import datetime
from itertools import groupby
from math import ceil
from operator import attrgetter

from webapp import app
from webapp.http import abort
from webapp.routing import redirect_to
from webapp.templating import output, render

from blog.model import Post


@output('index.html')
def index(request, response):
    return render(
        posts = list(Post.by_time(descending=True, count=10))
    )

@output('index.atom', mimetype='application/atom+xml')
def feed(request, response):
    page = int(request.GET.get('p', '1'))
    offset = (page - 1) * 10
    results = Post.by_time(descending=True, count=10, skip=offset)
    if not len(results):
        abort(404)
    return render(
        posts = list(results),
        num_pages = int(ceil(results.total_rows / 10)),
        page = page,
        per_page = 10,
    )

@output('post.html')
def post(request, response, year, month, slug):
    posts = list(Post.by_slug()[(year, month, slug)]) or abort(404)
    post = posts[0]
    prev = list(Post.by_time(count=-2, startkey_docid=post.id)
                [[post.published.isoformat()]:])
    next = list(Post.by_time(count=2, startkey_docid=post.id)
                [[post.published.isoformat()]:])
    return render(
        post = post,
        prev = len(prev) > 1 and prev[0] or None,
        next = len(next) > 1 and next[-1] or None
    )

@output('archives.html')
def archives(request, response):
    if 'tag' in request.POST:
        redirect_to(tag, request.POST['tag'])
    return render(
        months = Post.all_months(),
        tags = Post.all_tags()
    )

@output('tag.html')
def tag(request, response, tag):
    return render(
        tag = tag,
        tags = Post.all_tags(),
        posts = list(Post.by_tag()[[tag]:[tag, "9999"]]),
    )

@output('tag.atom', mimetype='application/atom+xml')
def tag_feed(request, response, tag):
    page = int(request.GET.get('p', '1'))
    offset = (page - 1) * 10
    results = Post.by_tag(descending=True, count=10, skip=offset) \
                         [[tag, "9999"]:[tag]]
    if not len(results):
        abort(404)
    return render(
        tag = tag,
        posts = list(results),
        num_pages = int(ceil(results.total_rows / 10)),
        page = page,
        per_page = 10,
    )

@output('month.html')
def month(request, response, year, month):
    posts = []
    prev = next = None
    for year_month, lst in groupby(Post.by_month(),
                                   lambda x: (x.published.year,
                                              x.published.month)):
        if year_month == (year, month):
            posts = list(lst)
        elif not posts:
            prev = year_month
        else:
            next = year_month
            break
    return render(
        posts = posts,
        month = datetime(year, month, 1),
        prev = prev and datetime(prev[0], prev[1], 1) or None,
        next = next and datetime(next[0], next[1], 1) or None
    )

@output('sitemap.xml')
def sitemap(request, response):
    return render(
        posts = list(Post.by_time(descending=True)),
        months = Post.all_months(),
        tags = Post.all_tags()
    )


