from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import Group
from django.core.cache import cache
from django.core.urlresolvers import reverse#, resolve
from django.core.paginator import Paginator, InvalidPage, EmptyPage
from django.http import (HttpResponseRedirect, HttpResponseForbidden )
from ldt.indexation import get_results_with_context, highlight_documents
from django.shortcuts import render_to_response
from django.template import RequestContext
from django.template.loader import render_to_string
from django.utils.html import escape
from django.utils.translation import ugettext as _
from ldt.ldt_utils.forms import SearchForm
from ldt.ldt_utils.models import Content, Project, Segment
from ldt.ldt_utils.utils import boolean_convert
from ldt.security.utils import add_change_attr, get_userlist
from lxml.html import fragment_fromstring
from ldt.ldt_utils.projectserializer import ProjectSerializer
from operator import itemgetter
from itertools import groupby
import base64
import django.core.urlresolvers
import ldt.auth as ldt_auth
import lxml.etree


@login_required
def home(request):
    
    # list of contents
    content_list = add_change_attr(request.user, Content.safe_objects.all()) #@UndefinedVariable
    
    # get list of projects owned by the current user
    project_list = add_change_attr(request.user, Project.safe_objects.filter(owner=request.user)) #@UndefinedVariable

    is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1);
    
    # Resolve a URL
    #project_api_view, project_api_args, project_api_kwargs = resolve('/api/ldt/projects/c8448f21-272d-11e1-876b-c8bcc896c290.json')
    #match = resolve('/api/ldt/projects/c8448f21-272d-11e1-876b-c8bcc896c290.json')
    
    # Print the URL pattern that matches the URL
    #print match.url_name
    
    # render list
    return render_to_response("ldt/ldt_utils/workspace.html",
                              {'contents': content_list, 'projects': project_list,
                               'is_gecko': is_gecko, #'project_api_url':"match.url_name",
                               #'project_api_view':match.url_name,'project_api_args':"project_api_args",'project_api_kwargs':"project_api_kwargs"
                               },
                              context_instance=RequestContext(request))

@login_required
def groups(request): 

    # get list of all published projects
    group_list = request.user.groups.exclude(name=settings.PUBLIC_GROUP_NAME)
    
    group_list = sorted(group_list.all(), key=lambda group: group.name.lower())    
    group_list = add_change_attr(request.user, group_list)

    can_add_group = request.user.has_perm('auth.add_group')
    is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1);
    # render list
    return render_to_response("ldt/ldt_utils/groups.html",
                              {'groups': group_list,
                               'is_gecko': is_gecko,
                               'can_add_group': can_add_group},
                              context_instance=RequestContext(request))


@login_required
def published_project(request): 

    # get list of all published projects
    project_list = Project.safe_objects.filter(state=2).exclude(title__startswith='front') #@UndefinedVariable
    # Search form
    form = SearchForm()

    is_gecko = ((request.META['HTTP_USER_AGENT'].lower().find("firefox")) > -1);
    
    # render list
    return render_to_response("ldt/ldt_utils/published_projects.html",
                              {'projects': project_list, 'form': form,
                               'is_gecko': is_gecko},
                              context_instance=RequestContext(request))


def popup_embed(request):

    json_url = request.GET.get("json_url")
    player_id = request.GET.get("player_id")
    ldt_id = request.GET.get("ldt_id")

    project = Project.safe_objects.get(ldt_id=ldt_id); #@UndefinedVariable

    stream_mode = project.stream_mode
    if stream_mode != "video":
        stream_mode = 'radio'

    player_width = 650
    player_height = 480
    
    if stream_mode == 'radio':
        player_height = 1
        
    if not ldt_auth.check_access(request.user, project):
        return HttpResponseForbidden(_("You can not access this project"))

    ps = ProjectSerializer(project, from_contents=False, from_display=True)
    annotations = ps.get_annotations(first_cutting=True)
    
    rend_dict = {'json_url':json_url, 'player_id':player_id, 'annotations':annotations, 'ldt_id': ldt_id, 'stream_mode': stream_mode, 'player_width': player_width, 'player_height': player_height}

    embed_rendered = dict((typestr,
                           (lambda s:escape(lxml.etree.tostring(fragment_fromstring(render_to_string("ldt/ldt_utils/partial/embed_%s.html" % (s), rend_dict, context_instance=RequestContext(request))), pretty_print=True)))(typestr))
                           for typestr in ('player', 'seo_body', 'seo_meta', 'links'))

    rend_dict['embed_rendered'] = embed_rendered

    return render_to_response("ldt/ldt_utils/embed_popup.html",
                              rend_dict,
                              context_instance=RequestContext(request))




def share_filter(request, filter, use_groups=False):
    use_groups = boolean_convert(use_groups)
    if not filter or len(filter) == 0:
        raise AttributeError("filter should be a string")
    
    filter = filter[1:]    
    resp = get_userlist(request.user, filter=filter)
            
    if use_groups:
        groups = Group.objects.filter(name__icontains=filter).exclude(name=settings.PUBLIC_GROUP_NAME)[0:20]

        for g in groups:
            resp.append({'name': g.name, 'id': g.id, 'type': 'group'})
    
    resp = sorted(resp, key=lambda elem: elem['name'].lower())
    
    return render_to_response("ldt/ldt_utils/partial/sharewith.html", {'elem_list' : resp}, context_instance=RequestContext(request))



def search_form(request): 
    form = SearchForm()
    return render_to_response('ldt/ldt_utils/search_form.html', {'form': form} , context_instance=RequestContext(request))


@login_required
def search_index(request, front_template=False):
        
    sform = SearchForm(request.POST)
    if sform.is_valid():
        search = sform.cleaned_data["search"]
        queryStr = base64.urlsafe_b64encode(search.encode('utf8'))
        field = request.POST["field"]
        language_code = request.LANGUAGE_CODE[:2]
        
        if request.POST.has_key("ldt_pres"):
            url = settings.WEB_URL + django.core.urlresolvers.reverse("ldt.ldt_utils.views.lignesdetemps.search_init", args=[field, queryStr])
            return render_to_response('ldt/ldt_utils/init_ldt_full.html', {'LDT_MEDIA_PREFIX': settings.LDT_MEDIA_PREFIX, 'colorurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/pkg/color.xml', 'i18nurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/pkg/i18n', 'language': language_code, 'baseurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/', 'url': url}, context_instance=RequestContext(request))
        else:
            results = get_results_with_context(field, search) 
            
            Segment.safe_objects.check_perm = False # no permission policy for segments
            all_segments = Segment.safe_objects.filter(element_id__in=[e['element_id'] for e in results])
            all_projects = Project.safe_objects.filter(ldt_id__in=[e['project_id'] for e in results], state=2)
            all_contents = Content.safe_objects.filter(iri_id__in=[e['iri_id'] for e in results])
            viewable_projects_id = [p.ldt_id for p in all_projects]
            
            complete_results = []           
            results.sort(key=lambda k: k['iri_id'])
            
            for iri_id, item in groupby(results, itemgetter('iri_id')):
                content = filter(lambda e: e.iri_id == iri_id, all_contents)[0]
                if content.description is None:
                    content.description = ''
                    
                all_related_segments = list(item)
                
                valid_segments = []
                for s in all_related_segments:
                    segment = [seg for seg in all_segments if seg.element_id == s['element_id'] and seg.project_id == s['project_id'] and seg.iri_id == s['iri_id'] and seg.cutting_id == s['decoupage_id'] and seg.ensemble_id == s['ensemble_id'] ][0]
                    
                    segment.score = s['score']
                    segment.lucene_id = s['lucene_id']
                    segment.context = s['context']
                    segment.context_tags = s['tags']
                                        
                    if not s['project_id']:
                        segment.project_id = '_'
                        valid_segments.append(segment)
                    elif s['project_id'] in viewable_projects_id:
                        valid_segments.append(segment)
                
                # If all segments found belong to unpublished projects or projects
                # the current user is not allowed to see
                if not valid_segments:
                    continue
                
                score = sum([seg.score for seg in valid_segments])
                complete_results.append({
                                         'list': valid_segments,
                                         'score': score,
                                         'content': content,                                         
                                         })
                
      
            complete_results.sort(key=lambda k: k['score'])
                                
            cache.set('complete_results_%s' % request.user.username, complete_results)
            cache.set('search_%s' % request.user.username, search)
            cache.set('field_%s' % request.user.username, field)

            paginator = Paginator (complete_results, settings.LDT_RESULTS_PER_PAGE)
            page = 1
            
            try:
                results = paginator.page(page)
            except (EmptyPage, InvalidPage):
                results = paginator.page(paginator.num_pages)
            
            results.object_list = highlight_documents(results.object_list, search, field)            
            
            if front_template :
                return render_to_response('front/front_search_results.html', {'results': results, 'nb_results' : paginator.count, 'search' : search, 'LDT_MEDIA_PREFIX': settings.LDT_MEDIA_PREFIX, 'colorurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/pkg/color.xml', 'i18nurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/pkg/i18n', 'language': language_code, 'baseurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/'}, context_instance=RequestContext(request))
            else :
                return render_to_response('ldt/ldt_utils/search_results.html', {'results': results, 'nb_results' : paginator.count, 'search' : search, 'LDT_MEDIA_PREFIX': settings.LDT_MEDIA_PREFIX, 'colorurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/pkg/color.xml', 'i18nurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/pkg/i18n', 'language': language_code, 'baseurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/'}, context_instance=RequestContext(request))
        
    else:
        if front_template :
            return HttpResponseRedirect(reverse('ldt.ldt_utils.views.front.front_home'))
        else :
            return HttpResponseRedirect(reverse('ldt.ldt_utils.views.workspace.published_project'))
        

def search_listing(request, front_template=False):
    if not cache.get('complete_results_%s' % request.user.username):
        if front_template :
            return HttpResponseRedirect(reverse('ldt.ldt_utils.views.front.front_home'))
        else :
            return HttpResponseRedirect(reverse('ldt.ldt_utils.views.workspace.published_project'))
     
    complete_results = cache.get('complete_results_%s' % request.user.username)
    search = cache.get('search_%s' % request.user.username)
    field = cache.get('field_%s' % request.user.username)
    paginator = Paginator(complete_results, settings.LDT_RESULTS_PER_PAGE)
    language_code = request.LANGUAGE_CODE[:2]

    try:
        page = int(request.GET.get('page', '1'))
    except ValueError:
        page = 1

    try:
        results = paginator.page(page)
    except (EmptyPage, InvalidPage):
        results = paginator.page(paginator.num_pages)
    
    results.object_list = highlight_documents(results.object_list, search, field)

    if front_template :
        return render_to_response('front/front_search_results.html', {'results': results, 'nb_results' : paginator.count, 'search' : search, 'LDT_MEDIA_PREFIX': settings.LDT_MEDIA_PREFIX, 'colorurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/pkg/color.xml', 'i18nurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/pkg/i18n', 'language': language_code, 'baseurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/'}, context_instance=RequestContext(request))
    else :
        return render_to_response('ldt/ldt_utils/search_results.html', {'results': results, 'nb_results' : paginator.count, 'search' : search, 'LDT_MEDIA_PREFIX': settings.LDT_MEDIA_PREFIX, 'colorurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/pkg/color.xml', 'i18nurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/pkg/i18n', 'language': language_code, 'baseurl': settings.LDT_MEDIA_PREFIX + 'swf/ldt/'}, context_instance=RequestContext(request))   
  




    

def loading(request): 
    return render_to_response('ldt/ldt_utils/loading.html', context_instance=RequestContext(request))


