import django.core.urlresolvers
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render_to_response, get_object_or_404, get_list_or_404
from django.template import RequestContext
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required
from django.conf import settings
from django.core import serializers
from django.utils import simplejson
from django.utils.html import escape
from fileimport import *
from forms import LdtImportForm, LdtAddForm, SearchForm, AddProjectForm, CopyProjectForm, ContentForm, MediaForm
from ldt.core.models import Owner
from models import *
from utils import *
from contentindexer import *
from projectserializer import *
from string import Template
from Ft.Xml import MarkupWriter
import cgi
import uuid
import base64
import lucene
import xml.dom
import xml.dom.ext
import xml.dom.minidom
import tempfile
import urllib2
from urllib2 import urlparse
from jogging import logging


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

def searchIndex(request):
    
    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]
    
        url = settings.WEB_URL + django.core.urlresolvers.reverse("ldt.ldt_utils.views.searchInit", args=[field, queryStr])
        return render_to_response('ldt/ldt_utils/init_ldt.html', {'MEDIA_URL': settings.MEDIA_URL, 'colorurl': settings.MEDIA_URL+'swf/ldt/pkg/color.xml', 'i18nurl': settings.MEDIA_URL+'swf/ldt/pkg/i18n', 'language': language_code, 'baseurl': settings.MEDIA_URL+'swf/ldt/', 'url': url}, context_instance=RequestContext(request))
    else:
        resp = HttpResponse()
        resp.write("<html><head></head><body>Error : No result</body></html>");

def searchIndexGet(request, field, query):

    language_code = request.LANGUAGE_CODE[:2]
    url = settings.WEB_URL + django.core.urlresolvers.reverse("ldt.ldt_utils.views.searchInit", args=[field, query])
    return render_to_response('irisuser/ldt/init_ldt.html', {'MEDIA_URL': settings.MEDIA_URL, 'colorurl': settings.MEDIA_URL+'swf/ldt/pkg/color.xml', 'i18nurl': settings.MEDIA_URL+'swf/ldt/pkg/i18n', 'language': language_code, 'baseurl': settings.MEDIA_URL+'swf/ldt/', 'url': url}, context_instance=RequestContext(request))

def searchInit(request, field, query):
    
    ldtgen = LdtUtils()
    
    doc = ldtgen.generateInit([field,query], 'ldt.ldt_utils.views.searchLdt', 'ldt.ldt_utils.views.searchSegments')
    
    resp = HttpResponse(mimetype="text/xml;charset=utf-8")
    xml.dom.ext.PrettyPrint(doc, resp)
    return resp

def searchLdt(request, field, query, edition=None):
    
    contentList = []
    resp = HttpResponse(mimetype="text/xml")
    queryStr = ""

    if query and len(query)>0:        
        queryStr = base64.urlsafe_b64decode(query.encode("ascii")).decode("utf8")
        searcher = LdtSearch()
        ids = {}
        
        for result in searcher.query(field, queryStr):
            ids[result["iri_id"]] = ""            

        id_list = ids.keys()
        
        if edition is not None:
            ids_editions = 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")))            
            id_list = filter(lambda id: id in id_list, ids_editions)
            
        contentList = Content.objects.filter(iri_id__in=id_list)        

            
    ldtgen = LdtUtils()
    ldtgen.generateLdt(contentList, file=resp, title = u"Recherche : " + queryStr)
    
    return resp


def searchSegments(request, field, query, edition=None):
    
    if query and len(query)>0:
        searcher = LdtSearch()
        
        queryStr = base64.urlsafe_b64decode(query.encode("ascii")).decode("utf8")
        res = searcher.query(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")))

    doc = xml.dom.getDOMImplementation().createDocument(None, "iri", None)

    for resultMap in res:
        if iri_ids is None or resultMap['iri_id'] in iri_ids:
            elem = doc.createElement('seg')
            elem.setAttribute('idctt', resultMap['iri_id'])
            elem.setAttribute('idens', resultMap['ensemble_id'])
            elem.setAttribute('iddec', resultMap['decoupage_id'])
            elem.setAttribute('idseg', resultMap['element_id'])
            elem.setAttribute('idvue', "")
            elem.setAttribute('crit', "")
            doc.documentElement.appendChild(elem)

    return HttpResponse(doc.toprettyxml(encoding='utf-8'), mimetype="text/xml;charset=utf-8")
    
@login_required         
def list_ldt(request):
    contents = Content.objects.all()
    try:
        owner = Owner.objects.get(user=request.user)
    except:
        return HttpResponseRedirect(settings.LOGIN_URL)
    ldtProjects = Project.objects.filter(owner=owner)
    context={
    'contents': contents,
    'projects': ldtProjects.reverse(),
    }
    return render_to_response('ldt/ldt_utils/ldt_list.html', context, context_instance=RequestContext(request))

@login_required         
def list_content(request):
    contents = Content.objects.all()
    context={
        'contents': contents,
    }
    return render_to_response('ldt/ldt_utils/content_list.html', context, context_instance=RequestContext(request))

@login_required
def create_ldt_view(request):
    if request.method == "POST" :
        form = LdtAddForm(request.POST)
        if form.is_valid():
            user = request.user
            Project.create_project(title=form.cleaned_data['title'], user=user, contents=form.cleaned_data['contents'])
            return HttpResponseRedirect(reverse("ldt.ldt_utils.views.list_ldt"))
    else:
        form = LdtAddForm()
        contents = Content.objects.all()    
        return render_to_response('ldt/ldt_utils/create_ldt.html', {'contents': contents, 'form': form,'create_project_action':reverse(create_ldt_view)}, context_instance=RequestContext(request))
     
def created_ldt(request):
    return render_to_response('ldt/ldt_utils/done.html', context_instance=RequestContext(request))
    
def indexProject(request, id):

    urlStr = settings.WEB_URL + reverse("space_ldt_init", args=['ldtProject', id])
    posturl= settings.WEB_URL + reverse("ldt.ldt_utils.views.save_ldtProject")
    language_code = request.LANGUAGE_CODE[:2]
    
    ldt = get_object_or_404(Project, ldt_id=id)
    if ldt.state ==2: #published
        readonly = 'true'
    else:
        readonly = 'false'
    
    return render_to_response('ldt/ldt_utils/init_ldt.html', {'MEDIA_URL': settings.MEDIA_URL, 'colorurl': settings.MEDIA_URL+'swf/ldt/pkg/color.xml', 'i18nurl': settings.MEDIA_URL+'swf/ldt/pkg/i18n', 'language': language_code, 'baseurl': settings.MEDIA_URL+'swf/ldt/', 'url': urlStr, 'posturl': posturl, 'id': id, 'readonly': readonly}, context_instance=RequestContext(request))
    
def init(request, method, url):
    ldtgen = LdtUtils()

    doc = ldtgen.generateInit([url], 'ldt.ldt_utils.views.'+method, None)

    resp = HttpResponse(mimetype="text/xml")
    resp['Cache-Control']='no-cache, must-revalidate'
    resp['Pragma']='no-cache'
    xml.dom.ext.PrettyPrint(doc, resp)
    return resp
       
def ldtProject(request, id):
    resp = HttpResponse(mimetype="text/xml")
    resp['Cache-Control']='no-cache, must-revalidate'
    resp['Pragma']='no-cache'
    
    project = Project.objects.get(ldt_id=id)
    resp.write(project.ldt)
    return resp


def project_json_id(request, id):
    
    project = get_object_or_404(Project,ldt_id=id)

    return project_json(request, project)


def project_json_externalid(request, id):
        
    res_proj = get_list_or_404(Project.objects.order_by('-modification_date'),contents__external_id = id)
    
    return project_json(request, res_proj[0])



def project_json(request, project):

    mimetype = request.REQUEST.get("mimetype")
    if mimetype is None:
        mimetype = "application/json; charset=utf-8"
    else:
        mimetype = mimetype.encode("utf-8")
    if "charset" not in mimetype:
        mimetype += "; charset=utf-8" 
    resp = HttpResponse(mimetype=mimetype)
    resp['Cache-Control']='no-cache, must-revalidate'
    resp['Pragma']='no-cache'
    
    indent = request.REQUEST.get("indent")
    if indent is None:
        indent = settings.LDT_JSON_DEFAULT_INDENT
    else:
        indent = int(indent)
    
    callback = request.REQUEST.get("callback")
    escape_str = request.REQUEST.get("escape")
    escape_bool = False
    if escape_str:
        escape_bool = {'true': True, 'false': False, "0": False, "1": True}.get(escape_str.lower())
        
        
    ps = ProjectSerializer(project)
    project_dict = ps.serialize_to_cinelab()
    
    json_str = simplejson.dumps(project_dict, ensure_ascii=False, indent=indent)
    
    if callback is not None:
        json_str = "%s(%s)" % (callback,json_str)
    
    if escape_bool:
        json_str = escape(json_str)
    
    resp.write(json_str)

    return resp


def save_ldtProject(request):
    if request.method=="POST":
        ldt = request.POST['ldt']
        id = request.POST['id']
        ldtproject=Project.objects.get(ldt_id=id)
        #save xml ldt
        ldtproject.ldt=ldt
        #get new title
        dom = xml.dom.minidom.parseString(ldt.encode( "utf-8" ))
        con = xml.xpath.Context.Context(dom, 1, 1, None)
        result = xml.xpath.Evaluate("/iri/project",context=con)
        for pnode in result:
            title=pnode.getAttribute("title")
            break
        #set new title
        ldtproject.title=title
        #get new content list
        new_contents=[]
        result = xml.xpath.Evaluate("/iri/medias/media", context=con)
        for medianode in result:
            id = medianode.attributes['id'].value
            new_contents.append(id)
        # set new content list
        for c in ldtproject.contents.all():
            if not c.iri_id in new_contents:
                ldtproject.contents.remove(c)           
        ldtproject.save()
    else:
        ldt = ''
    return render_to_response('ldt/ldt_utils/save_done.html', {'ldt': ldt, 'id':id, 'title':title, 'contents': new_contents}, context_instance=RequestContext(request))
    
@login_required    
def publish(request, id, redirect=True):
    ldt = get_object_or_404(Project, ldt_id=id)
    ldt.state = 2 #published
    ldt.save()
    redirect = boolean_convert(redirect)
    if redirect:
        return HttpResponseRedirect(reverse("ldt.ldt_utils.views.list_ldt"))
    else:
        return HttpResponse(simplejson.dumps({'res':True, 'ldt': {'id': ldt.id, 'state':ldt.state,'ldt_id': ldt.ldt_id}}, ensure_ascii=False),mimetype='application/json')
    
@login_required    
def unpublish(request, id, redirect=True):
    ldt = get_object_or_404(Project, ldt_id=id)
    ldt.state = 1 #edition
    ldt.save()
    redirect = boolean_convert(redirect)
    if redirect:
        return HttpResponseRedirect(reverse("ldt.ldt_utils.views.list_ldt"))
    else:
        return HttpResponse(simplejson.dumps({'res':True, 'ldt': {'id': ldt.id, 'state':ldt.state,'ldt_id': ldt.ldt_id}}, ensure_ascii=False),mimetype='application/json')
    

def index(request, url):
    
    urlStr = settings.WEB_URL + reverse("ldt_init", args=['ldt',url])
    language_code = request.LANGUAGE_CODE[:2]
    
    return render_to_response('ldt/ldt_utils/init_ldt.html', {'MEDIA_URL': settings.MEDIA_URL, 'colorurl': settings.MEDIA_URL+'swf/ldt/pkg/color.xml', 'i18nurl': settings.MEDIA_URL+'swf/ldt/pkg/i18n', 'language': language_code, 'baseurl': settings.MEDIA_URL+'swf/ldt/', 'url': urlStr, 'weburl':settings.WEB_URL+settings.BASE_URL}, context_instance=RequestContext(request))


def ldt(request, url, startSegment = None):

    import Ft
    from Ft.Xml import MarkupWriter
    
    resp = HttpResponse(mimetype="text/xml; charset=utf-8")
    resp['Cache-Control'] = 'no-cache'

    contentList = Content.objects.filter(iri_id=url)

    ldtgen = LdtUtils()
    ldtgen.generateLdt(contentList, file=resp, title = contentList[0].title, startSegment=startSegment)

    return resp


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


@login_required
def create_project(request, iri_id):

    content = get_object_or_404(Content, iri_id=iri_id)
    contents = [ content, ]
    if request.method == "POST" :
        form = AddProjectForm(request.POST)
        if form.is_valid():
            user=request.user
            project = Project.create_project(title=form.cleaned_data['title'], user=user, contents=contents)
            return HttpResponseRedirect(reverse('ldt.ldt_utils.views.indexProject', args=[project.ldt_id]))
    else:
        form = AddProjectForm()
    return render_to_response('ldt/ldt_utils/create_ldt.html', {'form':form, 'contents':contents, 'iri_id':iri_id, 'create_project_action':reverse("ldt.ldt_utils.views.create_project",args=[iri_id])}, context_instance=RequestContext(request))

@login_required
def copy_project(request, ldt_id):

    project = get_object_or_404(Project, ldt_id=ldt_id)
    if request.method == "POST" :
        form = CopyProjectForm(request.POST)
        if form.is_valid():
            user=request.user
            project = project.copy_project(title=request.POST['title'], user=user)
            return HttpResponseRedirect(reverse('ldt.ldt_utils.views.indexProject', args=[project.ldt_id]))
    else:
        form = CopyProjectForm
    return render_to_response('ldt/ldt_utils/copy_ldt.html', {'form':form, 'project':project}, context_instance=RequestContext(request))


def write_content_base(request, iri_id=None):

    if iri_id:        
        instance_content = Content.objects.get(iri_id=iri_id)
        instance_media = instance_content.media_obj
        logging.debug("write_content_base : valid form: for instance : media -> " + repr(instance_media) + " content : for instance : " + repr(instance_content) ) 
    else:
        logging.debug("No iri_id")
        instance_content = None
        instance_media = None
    
    form_status= 'none'        
    if request.method =="POST":
        content_form = ContentForm(request.POST, prefix="content", instance=instance_content)
        media_form = MediaForm(request.POST, request.FILES, prefix="media", instance= instance_media)
        media_valid = media_form.is_valid()
        content_valid = content_form.is_valid()
        
        logging.debug("write_content_base : valid form: for instance : " + repr(instance_media) + " -> media " + str(media_valid) +" content : for instance : " + repr(instance_content) + " : " + str(content_valid))
        
        if media_valid and content_valid :
            
            # see if media must be created
            cleaned_data = {}
            cleaned_data.update(media_form.cleaned_data)

            media_input_type = content_form.cleaned_data["media_input_type"]
            
            if media_input_type == "none":
                media = None
            elif media_input_type == "link":
                media = content_form.cleaned_data["media_obj"]
            elif media_input_type == "url" or  media_input_type == "upload" or  media_input_type == "create":                
                # copy file
                #complet src
                destination_file = None
                source_file = None
                destination_file_path = None
                if media_input_type != "create":
                    try:
                        if media_input_type == "url":
                            url = cleaned_data["external_src_url"]
                            source_file = urllib2.urlopen(url)
                            source_filename = source_file.info().get('Content-Disposition', None)
                            if not source_filename:
                                source_filename = urlparse.urlparse(url).path.rstrip("/").split('/')[-1]
                        elif media_input_type == "upload":
                            source_file = request.FILES['media-media_file']
                            source_filename = source_file.name
                            
    
                        destination_filepath = os.path.join(settings.STREAM_PATH, source_filename)
                        base_source_filename = source_filename
                        i = 0
                        while os.path.exists(destination_filepath):
                            base_source_filename = source_filename+"(%d)" % (i)
                            destination_filepath = os.path.join(settings.STREAM_PATH, base_source_filename)
                            i += 1
                            
                        destination_file = open(destination_filepath, "w")
                        src_prefix = settings.STREAM_SRC_PREFIX.rstrip("/")
                        if len(src_prefix) > 0:
                            cleaned_data["src"] = src_prefix + "/" + base_source_filename
                        else:
                            cleaned_data["src"] =  base_source_filename
                        
                        chunck = source_file.read(2048)
                        while chunck:
                            destination_file.write(chunck)
                            chunck = source_file.read(2048)
            
                    except Exception as inst:
                        logging.debug("write_content_base : POST error when processing file:" + str(inst))
                        form_status = "error"
                    finally:
                        if destination_file:
                            destination_file.close()
                        if source_file:
                            source_file.close()
                        
                if form_status != "error":
                    #try:
                    del cleaned_data["media_file"]
                    if not cleaned_data['videopath']:
                        cleaned_data['videopath'] = settings.STREAM_URL
                    media, created = Media.objects.get_or_create(src=cleaned_data['src'], defaults=cleaned_data)
                    if not created:                        
                        for attribute in ('external_id', 'external_permalink', 'external_publication_url', 'external_src_url', 'media_creation_date', 'videopath', 'duration', 'description', 'title'):
                            setattr(media, attribute, cleaned_data.get(attribute))
                    media.save()
                    #except Exception as inst:
#                        logging.debug("write_content_base : POST error when saving media:" + str(inst))
 #                       form_status = "error"
                        #TODO: set error message
                        #media_form.errors = _("Error when saving the media : " + e.message)

            #if needed preparetemp file and copy temp file to destination
            
            
            if form_status != "error":
                #try:
                content_defaults = {}
                content_defaults.update(content_form.cleaned_data)
                content_defaults['media_obj'] = media
                del content_defaults["media_input_type"]
                content, created = Content.objects.get_or_create(iri_id = content_form.cleaned_data['iri_id'], defaults = content_defaults)
                if not created:
                    
                    for attribute in ('iriurl', 'title', 'description', 'duration', 'content_creation_date', 'tags', 'media_obj'):
                        setattr(content, attribute, content_defaults[attribute])
                content.save()
                form_status = 'saved'
                media_form = MediaForm(instance=media, prefix="media")
                content_form = ContentForm(instance=content, prefix="content")
                #except:
                    #logging.debug("write_content_base : POST error when saving content:" + str(inst))
                    #form_status = "error"
                    #TODO : set error on content form
        else:
            form_status = 'error'
    else:
        form_status = 'empty'
        initial = { 'media_input_type':"link"}
        
        content_form = ContentForm(prefix="content", instance=instance_content, initial = initial )
        media_form = MediaForm(prefix="media", instance=instance_media)
        
        if instance_content is not None:
            content_form.media_input_type = "link"
    
    return content_form, media_form, form_status


def write_content(request, iri_id=None):
    
    logging.debug("write_content : " + str(iri_id) )
    content_form, media_form, form_status = write_content_base(request, iri_id)
    
    if iri_id:
        create_content_action =  reverse(write_content, kwargs={'iri_id':iri_id})
    else:
        create_content_action =  reverse(write_content)
    
    return render_to_response('ldt/ldt_utils/create_content.html', {'content_form': content_form, 'media_form': media_form,'form_status': form_status,'create_content_action': create_content_action}, context_instance=RequestContext(request))


    