from django import http
from django.conf import settings
from django.core.exceptions import PermissionDenied
from django.shortcuts import get_object_or_404, redirect, render
from django.template import Context, loader

import commonware.log
from tower import ugettext as _
from mobility.decorators import mobile_template
from waffle.decorators import waffle_switch

import amo
from amo import messages
from amo.decorators import (json_view, login_required, post_required,
                            restricted_content)
from amo.helpers import absolutify, shared_url
import amo.utils
from access import acl
from addons.decorators import addon_view_factory
from addons.models import Addon

from .helpers import user_can_delete_review
from .models import Review, ReviewFlag, GroupedRating, Spam
from . import forms

import HTMLParser
import json
import requests

log = commonware.log.getLogger('z.reviews')
addon_view = addon_view_factory(qs=Addon.objects.valid)


def send_mail(template, subject, emails, context, perm_setting):
    template = loader.get_template(template)
    amo.utils.send_mail(subject, template.render(Context(context,
                                                         autoescape=False)),
                        recipient_list=emails, perm_setting=perm_setting)


@addon_view
@mobile_template('reviews/{mobile/}review_list.html')
def review_list(request, addon, review_id=None, user_id=None, template=None):
    q = (Review.objects.valid().filter(addon=addon)
         .order_by('-created'))

    ctx = {'addon': addon,
           'grouped_ratings': GroupedRating.get(addon.id)}

    ctx['form'] = forms.ReviewForm(None)

    if review_id is not None:
        ctx['page'] = 'detail'
        # If this is a dev reply, find the first msg for context.
        review = get_object_or_404(Review.objects.all(), pk=review_id)
        if review.reply_to_id:
            review_id = review.reply_to_id
            ctx['reply'] = review
        q = q.filter(pk=review_id)
    elif user_id is not None:
        ctx['page'] = 'user'
        q = q.filter(user=user_id)
        if not q:
            raise http.Http404()
    else:
        ctx['page'] = 'list'
        q = q.filter(is_latest=True)

    ctx['reviews'] = reviews = amo.utils.paginate(request, q)
    ctx['replies'] = Review.get_replies(reviews.object_list)
    if request.user.is_authenticated():
        ctx['review_perms'] = {
            'is_admin': acl.action_allowed(request, 'Addons', 'Edit'),
            'is_editor': acl.check_reviewer(request),
            'is_author': acl.check_addon_ownership(request, addon, viewer=True,
                                                   dev=True, support=True),
        }
        ctx['flags'] = get_flags(request, reviews.object_list)
    else:
        ctx['review_perms'] = {}
    return render(request, template, ctx)


def get_flags(request, reviews):
    reviews = [r.id for r in reviews]
    qs = ReviewFlag.objects.filter(review__in=reviews, user=request.user.id)
    return dict((r.review_id, r) for r in qs)


def _retrieve_translation(text, language):
    try:
        r = requests.get(
            settings.GOOGLE_TRANSLATE_API_URL, params={
                'key': getattr(settings, 'GOOGLE_API_CREDENTIALS', ''),
                'q': text, 'target': language})
    except Exception, e:
        log.error(e)
    try:
        translated = (HTMLParser.HTMLParser().unescape(r.json()['data']
                      ['translations'][0]['translatedText']))
    except (KeyError, IndexError):
        translated = ''
    return translated, r


def translate_review(request, review, language):
    """
    Shared view splitted from the translate() views below for reusability
    purposes (This is shared with mkt.reviewers).
    """
    if '-' in language:
        language = language.split('-')[0]

    if request.is_ajax():
        title, r = _retrieve_translation(review.title, language)
        body, r = _retrieve_translation(review.body, language)
        return http.HttpResponse(json.dumps({'title': title, 'body': body}),
                                 status=r.status_code)
    else:
        return redirect(settings.GOOGLE_TRANSLATE_REDIRECT_URL.format(
            lang=language, text=review.body))


@addon_view
@waffle_switch('reviews-translate')
def translate(request, addon, review_id, language):