import base64
import logging

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.core.urlresolvers import reverse
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404
from django.template import RequestContext
from django.views.decorators.cache import never_cache
import lxml.etree

from ldt.indexation import SimpleSearch
from ldt.ldt_utils.models import Content, Project, Media, Segment
from ldt.ldt_utils.searchutils import search_generate_ldt
from ldt.ldt_utils.stat import update_stat_project
from ldt.ldt_utils.utils import LdtUtils, clean_description
from ldt.security.permissionchecker import check_object_perm_for_user
from ldt.security.utils import set_forbidden_stream
from ldt.utils.projectldt_parser import absolute_src_xml, relative_src_xml
from ldt.utils.url import static, absurl, absstatic
from ldt.utils.web_url_management import get_web_url


logger = logging.getLogger(__name__)

def search_index_get(request, field, query):
    
    language_code = request.LANGUAGE_CODE[:2]
    
    url = absurl(request, "ldt.ldt_utils.views.lignesdetemps.search_init", kwargs={'field':field, 'query':query})
    colorurl=static("ldt/swf/ldt/pkg/color.xml")
    i18nurl=static("ldt/swf/ldt/pkg/i18n")
    baseurl=static("ldt/swf/ldt/")
    return render_to_response('ldt/ldt_utils/init_ldt.html', {'colorurl': colorurl, 'i18nurl': i18nurl, 'language': language_code, 'baseurl': baseurl, 'url': url}, context_instance=RequestContext(request))

def search_init(request, field, query):
    
    ldtgen = LdtUtils()
    
    doc = ldtgen.generate_init({'field':field, 'query':query}, 'ldt.ldt_utils.views.lignesdetemps.search_ldt', 'ldt.ldt_utils.views.lignesdetemps.search_segments')
    
    resp = HttpResponse(mimetype="text/xml;charset=utf-8")
    resp.write(lxml.etree.tostring(doc, pretty_print=True, encoding="utf-8")) 
    return resp


def search_ldt(request, field, query, edition=None, return_project=False, query_encoded=True): 
    
    resp = HttpResponse(mimetype="text/xml")
    doc, _ = search_generate_ldt(request, field, query)
    doc = absolute_src_xml(doc)
    doc.write(resp, pretty_print=True)
    
    return resp


def search_segments(request, field, query, edition=None):
    
    if query and len(query) > 0:
        searcher = SimpleSearch()
        
        queryStr = base64.urlsafe_b64decode(query.encode("ascii")).decode("utf8")
        res = searcher.query(Segment, field, queryStr)            
    else:
        res = []
        
    iri_ids = None
    
    #if edition is not None:
    #    iri_ids = map(lambda t:t[0], filter(lambda id: id[0] is not None, Speak.objects.filter(session__day__edition=edition).order_by("session__start_ts", "order").values_list("content__iri_id")))

    iri = lxml.etree.Element('iri')
    doc = lxml.etree.ElementTree(iri)

    for resultMap in res:
        if iri_ids is None or resultMap['iri_id'] in iri_ids:
            seg = lxml.etree.SubElement(iri, 'seg')
            seg.set('idctt', resultMap['iri_id'])
            seg.set('idens', resultMap['ensemble_id'])
            seg.set('iddec', resultMap['cutting_id'])
            seg.set('idseg', resultMap['element_id'])
            seg.set('idvue', "")
            seg.set('crit', "")
    
    #return doc  
    
    return HttpResponse(lxml.etree.tostring(doc, pretty_print=True), mimetype="text/xml;charset=utf-8") 



def index_segment(request, project_id, content_id, cutting_id, ensemble_id, segment_id):
    url_str = absurl(request, "ldt.ldt_utils.views.lignesdetemps.init_segment", kwargs={'project_id':project_id, 'content_id':content_id, 'ensemble_id':ensemble_id, 'cutting_id':cutting_id, 'segment_id':segment_id})
    post_url = ""
    language_code = request.LANGUAGE_CODE[:2]
    readonly = 'true'
    template_path = 'ldt/ldt_utils/init_ldt.html'
    colorurl=static("ldt/swf/ldt/pkg/color.xml")
    i18nurl=static("ldt/swf/ldt/pkg/i18n")
    baseurl=static("ldt/swf/ldt/")
    return render_to_response(template_path, {'colorurl': colorurl, 'i18nurl': i18nurl, 'language': language_code, 'baseurl': baseurl, 'url': url_str, 'posturl': post_url, 'id': id, 'readonly': readonly}, context_instance=RequestContext(request))
    
def init_segment(request, project_id, content_id, ensemble_id, cutting_id, segment_id):

    if project_id != u"_":
        get_object_or_404(Project.safe_objects, ldt_id=project_id)
    
    ldtgen = LdtUtils()
    doc = ldtgen.generate_init({'project_id':project_id, 'content_id':content_id, 'ensemble_id':ensemble_id, 'cutting_id':cutting_id, 'segment_id':segment_id}, 'ldt.ldt_utils.views.lignesdetemps.ldt_segment', 'ldt.ldt_utils.views.lignesdetemps.highlight_segment')
    return HttpResponse(lxml.etree.tostring(lxml.etree.ElementTree(doc), pretty_print=True), mimetype="text/xml;charset=utf-8")

def highlight_segment(request, project_id, content_id, ensemble_id, cutting_id, segment_id):
    if project_id != u"_":
        get_object_or_404(Project.safe_objects, ldt_id=project_id)
    
    iri = lxml.etree.Element('iri')
    doc = lxml.etree.ElementTree(iri)    

    seg = lxml.etree.SubElement(iri, 'seg')
    seg.set('idctt', content_id)
    seg.set('idens', ensemble_id)
    seg.set('iddec', cutting_id)
    seg.set('idseg', segment_id)
    seg.set('idvue', "")
    seg.set('crit', "")
  
    return HttpResponse(lxml.etree.tostring(doc, pretty_print=True), mimetype="text/xml;charset=utf-8") 


def ldt_segment(request, project_id, content_id, ensemble_id, cutting_id, segment_id): 

    resp = HttpResponse(mimetype="text/xml")
    resp['Cache-Control'] = 'no-cache, must-revalidate'
    resp['Pragma'] = 'no-cache'
    
    if project_id and project_id != "_" :
        project = Project.safe_objects.get(ldt_id=project_id) #@UndefinedVariable
        ldtdoc = lxml.etree.fromstring(project.ldt_encoded)
        ldtdoc = absolute_src_xml(ldtdoc)
        ldtdoc = set_forbidden_stream(ldtdoc, request.user)
        displays_node = ldtdoc.find("displays")
        if not displays_node:
            displays_node = lxml.etree.SubElement(ldtdoc, u"displays")
        res = displays_node.xpath("display")
        if len(res) > 0:
            display_node = res[0]
        else:
            display_node = lxml.etree.SubElement(displays_node, u"display", attrib={u'id':u'0', u'title': u'generated', u'idsel':unicode(content_id), u'tc':u'0'})
        
        res = display_node.xpath("content[@id='%s']/decoupage[(@id='%s') and (@idens='%s')]" % (content_id, cutting_id, ensemble_id))
        if len(res) == 0:
            #create node
            res = display_node.xpath("content[@id='%s']" % (content_id))
            if len(res) == 0:
                content_node = lxml.etree.SubElement(display_node, u"content")
            else:
                content_node = res[0]
            lxml.etree.SubElement(content_node, u"decoupage", attrib={u'id':unicode(cutting_id), u'idens':unicode(ensemble_id)})
        active_segment_node = displays_node.find(u"activeSegment")
        if not active_segment_node:
            active_segment_node = lxml.etree.SubElement(displays_node, u"activeSegment")
        id_node = active_segment_node.find(u"id")
        if id_node:
            active_segment_node.remove(id_node)
        lxml.etree.SubElement(active_segment_node, u"id", attrib={u"idctt":unicode(content_id), u"idens": unicode(ensemble_id), "idcut":unicode(cutting_id), u"idseg":unicode(segment_id)})                     
        ldtdoc = set_forbidden_stream(ldtdoc, request.user)
        resp.write(lxml.etree.tostring(ldtdoc, xml_declaration=True, encoding='utf-8', pretty_print=True))
    else:
        # generate ldt from 
        ldtgen = LdtUtils()
        content_list = Content.safe_objects.filter(iri_id=content_id)
        if request.user and request.user.username:
            username = request.user.username
        else:
            username = "webuser"
        
        start_segment = {
            'idcontent': content_id,
            'idgroup' : ensemble_id,
            'idcutting' : cutting_id,
            'idsegment' : segment_id
        }        
        
        doc = ldtgen.generate_ldt(content_list, "segment : ", author=username, startSegment=start_segment)
        doc = absolute_src_xml(doc)
        doc = set_forbidden_stream(doc, request.user)
        doc.write(resp, pretty_print=('DEBUG' in dir(settings) and settings.DEBUG))
        
    return resp
        
   
@login_required    
def index_project(request, id, full=False):  # @ReservedAssignment

    urlStr = absurl(request, "ldt.ldt_utils.views.lignesdetemps.init", kwargs={'method':'ldt_project', 'url':id})
    posturl = absurl(request, "ldt.ldt_utils.views.lignesdetemps.save_ldt_project")
    language_code = request.LANGUAGE_CODE[:2]
    colorurl = static("ldt/swf/ldt/pkg/color.xml")
    i18nurl = static("ldt/swf/ldt/pkg/i18n")
    baseurl = static("ldt/swf/ldt/")
    audio_record_url = None
    
    try:
        ldt = Project.safe_objects.get(ldt_id=id)
    except Project.DoesNotExist:
        return HttpResponseRedirect(reverse("ldt.ldt_utils.views.workspace.home"))
    
    if ldt.state == 2 or not check_object_perm_for_user(ldt, 'change_project', request.user):
        readonly = 'true'
    else:
        readonly = 'false'
        # Add audio annotation feature if possible
        if hasattr(settings, "AUDIO_RECORD_URL"):
            if settings.AUDIO_RECORD_URL and settings.AUDIO_RECORD_URL!="":
                audio_record_url = settings.AUDIO_RECORD_URL
    
    if full:
        template_path = 'ldt/ldt_utils/init_ldt_full.html'
    else:
        template_path = 'ldt/ldt_utils/init_ldt.html'
    
    return render_to_response(template_path,
                              {'colorurl': colorurl, 'i18nurl': i18nurl, 'language': language_code,
                                'baseurl': baseurl, 'url': urlStr, 'posturl': posturl,
                                'id': id, 'readonly': readonly, 'audio_record_url': audio_record_url},
                              context_instance=RequestContext(request))
    

def embed_ldt(request, id):  # @ReservedAssignment
    # Almost identical to index_project but without login_required and less parameters
    urlStr = absurl(request, "ldt.ldt_utils.views.lignesdetemps.init", kwargs={'method':'ldt_project', 'url':id})
    posturl = ""
    language_code = request.LANGUAGE_CODE[:2]
    colorurl = absstatic(request, "ldt/swf/ldt/pkg/color.xml")
    i18nurl = absstatic(request, "ldt/swf/ldt/pkg/i18n")
    baseurl = absstatic(request, "ldt/swf/ldt/")
    
    readonly = 'true'
    template_path = 'ldt/ldt_utils/embed_ldt.html'
    
    try:
        _ = Project.safe_objects.get(ldt_id=id)
    except Project.DoesNotExist:
        return HttpResponseRedirect(reverse("ldt.ldt_utils.views.workspace.home"))
    
    return render_to_response(template_path, {'colorurl': colorurl, 'i18nurl': i18nurl, 'language': language_code, 'baseurl': baseurl, 'url': urlStr, 'posturl': posturl, 'id': id, 'readonly': readonly}, context_instance=RequestContext(request))
    
    
def init(request, method, url):
    ldtgen = LdtUtils()
    if method in ["init","index","ldt"]:
        param = "url"
    else:
        param = "id"
    doc = ldtgen.generate_init({param:url}, 'ldt.ldt_utils.views.lignesdetemps.' + method, None)

    library = doc.xpath('/iri/files/library')[0]
    for c in Content.safe_objects.all().select_related("media_obj"):
        elem = lxml.etree.SubElement(library, 'file')
        elem.set('src', c.iri_url())
        if c.videopath :
            elem.set('video', c.videopath)
        else :
            elem.set('video', '')
        elem.set('title', c.title or '')
        elem.set('author', '')
        elem.set('category', '')
        elem.set('pict', '')
        elem.set('img', '')

    resp = HttpResponse(mimetype="text/xml")
    resp['Cache-Control'] = 'no-cache, must-revalidate'
    resp['Pragma'] = 'no-cache'

    resp.write(lxml.etree.tostring(doc, pretty_print=True, xml_declaration=True, encoding="utf-8")) 
    return resp

@never_cache   
def ldt_project(request, id):  # @ReservedAssignment
    resp = HttpResponse(mimetype="text/xml")
    resp['Cache-Control'] = 'no-cache, must-revalidate'
    resp['Pragma'] = 'no-cache'
    
    project = Project.safe_objects.get(ldt_id=id) #@UndefinedVariable
    
    doc = lxml.etree.fromstring(project.ldt_encoded)
    doc = set_forbidden_stream(doc, request.user)
    doc = absolute_src_xml(doc)
    resp.write(lxml.etree.tostring(doc, pretty_print=True, xml_declaration=True, encoding="utf-8")) 

    return resp



def save_ldt_project(request):
    if request.method == "POST":
        ldt = request.POST['ldt']
        ldt_id = request.POST['id']
        ldtproject = Project.safe_objects.select_related().get(ldt_id=ldt_id) #@UndefinedVariable
        ldtxml=lxml.etree.fromstring(ldt)
        #save xml ldt
        ldt, _, _ = relative_src_xml(ldtxml)
        ldt = lxml.etree.tostring(ldt, pretty_print=True)          
        ldtproject.ldt = ldt
        
        doc = lxml.etree.fromstring(ldtproject.ldt_encoded)
        result = doc.xpath("/iri/project")
        
        #set new title
        ldtproject.title = result[0].get("title")
        
        #get new content list
        new_contents = []
        result = doc.xpath("/iri/medias/media")
        for medianode in result:
            media_id = medianode.get("id")
            new_contents.append(media_id)
            #Put back the video fied from "forbidden_stream_url" to the video url
            if medianode.get("video") == settings.FORBIDDEN_STREAM_URL:
                content = Content.objects.get(iri_id=media_id)
                media = Media.objects.get(id=content.media_obj.id)
                medianode.set('video', media.videopath)
                ldtproject.ldt = lxml.etree.tostring(doc, pretty_print=True)
    
        check_icon_project = False
        
        #find contents to remove
        for c in ldtproject.contents.all():
            if not c.iri_id in new_contents:
                ldtproject.contents.remove(c)
                if ldtproject.image == c.image:
                    check_icon_project = True
        
        #add new contents
        contents_id = [c.iri_id for c in ldtproject.contents.all()]
        
        for c in new_contents:
            if c not in contents_id:
                content = Content.objects.get(iri_id=c)
                ldtproject.contents.add(content)
         
        update_stat_project(ldtproject)
        
        #remove html tags added by flash
        description = ldtproject.get_description(doc)
        new_desc = clean_description(description)
        
        if new_desc:
            desc_node = doc.xpath('/iri/project')[0]
            desc_node.set('abstract', new_desc)
            ldtproject.ldt = lxml.etree.tostring(doc, pretty_print=True)
        
        ldtproject.description = new_desc if new_desc else description
    
        #set a new icon for this project
        if check_icon_project:
            ldtproject.set_icon()
        
        ldtproject.save()
        
    else:
        ldt = ''
        new_contents = []
    
    return render_to_response('ldt/ldt_utils/save_done.html', {'ldt': ldt, 'id':ldt_id, 'title':ldtproject.title, 'contents': new_contents}, context_instance=RequestContext(request))
    

def index(request, url):
    
    urlStr = absurl(request, "ldt.ldt_utils.views.lignesdetemps.init", kwargs={'method':'ldt', 'url':url})
    language_code = request.LANGUAGE_CODE[:2]
    colorurl=absstatic(request, "ldt/swf/ldt/pkg/color.xml")
    i18nurl=absstatic(request, "ldt/swf/ldt/pkg/i18n")
    baseurl=absstatic(request, "ldt/swf/ldt/")
    return render_to_response('ldt/ldt_utils/init_ldt.html', {'colorurl': colorurl, 'i18nurl': i18nurl, 'language': language_code, 'baseurl': baseurl, 'url': urlStr, 'weburl': get_web_url(request) + settings.BASE_URL}, context_instance=RequestContext(request))


def ldt(request, url, startSegment=None): 
    
    resp = HttpResponse(mimetype="text/xml; charset=utf-8")
    resp['Cache-Control'] = 'no-cache'

    contentList = Content.safe_objects.filter(iri_id=url) #@UndefinedVariable

    ldtgen = LdtUtils()
    doc = ldtgen.generate_ldt(contentList, title=contentList[0].title, startSegment=startSegment)
    doc = set_forbidden_stream(doc, request.user)
    doc = absolute_src_xml(doc)
    doc.write(resp, pretty_print=True)

    return resp


