#!/usr/bin/env python2
#
# Copyright 2016 Red Hat, Inc.
#
# Authors:
#     Fam Zheng <famz@redhat.com>
#
# This work is licensed under the MIT License.  Please see the LICENSE file or
# http://opensource.org/licenses/MIT.

from django.shortcuts import render
from django.views.generic import View
from django.contrib.auth import authenticate, login, logout
from django.http import HttpResponse, Http404
from django.core.exceptions import PermissionDenied
from django.conf import settings
from .models import Project, Message
import json
from search import SearchEngine
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator

class APIView(View):
    name = None

    @method_decorator(csrf_exempt)
    def dispatch(self, request, *args, **kwargs):
        return super(APIView, self).dispatch(request, *args, **kwargs)

    def get(self, request):
        raise PermissionDenied("API must use POST method")

    def handle(self, request, **params):
        raise Http404("unknown command")

    def check_request(self, request):
        pass

    def post(self, request):
        p = request.POST.get("params")
        if p:
            params = json.loads(p)
        else:
            params = {}
        self.check_request(request)
        r = self.handle(request, **params)
        if r:
            return HttpResponse(json.dumps(r))
        else:
            return HttpResponse()

class APILoginRequiredView(APIView):

    allowed_groups = []

    def check_permission(self, request):
        return False

    def check_request(self, request):
        if not request.user.is_authenticated():
            raise PermissionDenied()
        if request.user.is_superuser:
            return
        for grp in request.user.groups.all():
            if grp.name in self.allowed_groups or \
                    self.check_permission(request):
                return
        raise PermissionDenied()

class VersionView(APIView):
    name = "version"

    def handle(self, request):
        return settings.VERSION

def render_project(p):
    ret = {
        "name": p.name,
        "mailing_list": p.mailing_list,
        "url": p.url,
        "git": p.git,
        "description": p.description,
    }
    return ret

class ListProjectView(APIView):
    name = "get-projects"

    def handle(self, request):
        r = [render_project(x) for x in Project.objects.all()]
        return r

class AddProjectView(APILoginRequiredView):
    name = "add-project"

    def handle(self, request, name, mailing_list, url, git, description):
        if Project.objects.filter(name=name):
            raise Exception("Project already exists")
        p = Project(name=name,
                    mailing_list=mailing_list,
                    url=url,
                    git=git,
                    description=description)
        p.save()

class GetProjectPropertiesView(APILoginRequiredView):
    name = "get-project-properties"

    def handle(self, request, project):
        po = Project.objects.get(name=project)
        if not po.maintained_by(request.user):
            raise PermissionDenied("Access denied to this project")
        return po.get_properties()

class SetProjectPropertiesView(APILoginRequiredView):
    name = "set-project-properties"

    def handle(self, request, project, properties):
        po = Project.objects.get(name=project)
        if not po.maintained_by(request.user):
            raise PermissionDenied("Access denied to this project")
        for k, v in properties.iteritems():
            po.set_property(k, v)

def render_patch(p):
    r = {"subject": p.subject,
         "message-id": p.message_id,
         "mbox": p.get_mbox(),
         "properties": p.get_properties(),
         }
    return r

def render_series(s):
    r = {"subject": s.subject,
         "project": s.project.name,
         "message-id": s.message_id,
         "patches": [render_patch(x) for x in s.get_patches()],
         "properties": s.get_properties(),
         "is_complete": s.is_complete,
         }
    return r

class SearchView(APIView):
    name = "search"

    def handle(self, request, terms):
        se = SearchEngine()
        r = se.search_series(*terms)
        return [render_series(x) for x in r]

class ImportView(APILoginRequiredView):
    name = "import"
    allowed_groups = ["importers"]

    def handle(self, request, mboxes):
        for mbox in mboxes:
            try:
                Message.objects.add_message_from_mbox(mbox.encode("utf8"), request.user)
            except Message.objects.DuplicateMessageError:
                pass

class DeletreView(APILoginRequiredView):
    """ Delete messages """
    name = "delete"

    def handle(self, request, terms=[]):
        if not terms:
            Message.objects.all().delete()
        else:
            se = SearchEngine()
            for r in se.search_series(*terms):
                Message.objects.delete_subthread(r)

class Logout(APIView):
    name = "logout"

    def handle(self, request):
        logout(request)

class LoginComand(APIView):
    name = "login"

    def handle(self, request, username, password):
        user = authenticate(username=username, password=password)
        if user is not None:
            # the password verified for the user
            if user.is_active:
                login(request, user)
                return
            else:
                raise Exception("User is disabled")
        else:
                raise PermissionDenied("Wrong user name or password")


@@ -2062,22 +2062,23 @@
 ON%0A%0Adef 
+p
 re
-nder
+pare
 _project
@@ -2365,22 +2365,23 @@
    r = %5B
+p
 re
-nder
+pare
 _project
@@ -3594,22 +3594,23 @@
 v)%0A%0Adef 
+p
 re
-nder
+pare
 _patch(p
@@ -3783,30 +3783,31 @@
  r%0A%0Adef 
+p
 re
-nder
+pare
 _series(
 s):%0A    
@@ -3798,16 +3798,25 @@
 _series(
+request, 
 s):%0A    
@@ -4257,22 +4257,23 @@
 rn %5B
+p
 re
-nder
+pare
 _series(
 x) f
@@ -4268,16 +4268,25 @@
 _series(
+request, 
 x) for x

Rename render_* to prepare_*