from django.conf import settings
from ldt.ldt_utils.stat import get_string_from_buckets
from ldt.security.utils import use_forbidden_url
from tagging.utils import parse_tag_input
import logging
import lxml.etree
import uuid

logger = logging.getLogger(__name__)

DATE_FORMATS = ["%d/%m/%Y", "%Y-%m-%d"]

class SegmentSerializer(object):
    """
    Serialize a set of annotations to a cinelab compatible array
    """
    
    def __init__(self, content, segments, viewable_contents=[], default_color=2194379):
        """
        viewable_contents should contain all contents from project that a user is allowed to see. The settings.FORBIDDDEN_STREAM_URL
        will be displayed if a content is not found in viewable_contents, and the real stream will be displayed if it is. 
        """
        self.content = content
        self.segments = segments
        self.viewable_contents = viewable_contents
        self.default_color = default_color
        self.views = None
        self.annotation_types = None
        self.medias = None
        self.annotations = None 
        self.tags = {}
               
        self.xml_docs = {}
        
    def __get_cutting_title(self, project_id, content_id, ensemble_id, cutting_id, project):
        
        if not self.xml_docs.has_key(project_id):
            if not project:
                return None
            doc = lxml.etree.fromstring(project.ldt_encoded)
            self.xml_docs[project_id] = doc
        else:
            doc = self.xml_docs[project_id]
              
        cutting = doc.xpath('/iri/annotations/content[@id=\'%s\']/ensemble[@id=\'%s\']/decoupage[@id=\'%s\']/title' % (content_id, ensemble_id, cutting_id))
        if not cutting:
            return None
        
        cutting = cutting[0]
        
        return cutting.text       
    
    def __parse_views(self):
        
        view = {
                "id": "0",
                "contents": [
                    self.content.iri_id
                ],
                "annotation_types": [ ],
        }
        
        stat = {
                "id": "stat",
                "contents": [
                    self.content.iri_id
                ],
                "meta": {
                    "stat": get_string_from_buckets(self.content.annotation_volume)
                }
        }
        
        self.annotation_types = []

        annotation_types = []        
        for seg in self.segments:
            title = self.__get_cutting_title(seg.project_id, seg.iri_id, seg.ensemble_id, seg.cutting_id, seg.project_obj)
            annotation_types.append({'id': seg.cutting_id, 'title': title})
        
        for a in annotation_types:
                                            
            view['annotation_types'].append(a['id'])
            self.annotation_types.append({
                    "dc:contributor": "undefined",
                    "dc:creator": "undefined",
                    "dc:title": a['title'],
                    "id": a['id'],
                    "dc:created": "",
                    "dc:description": "",
                    "dc:modified": ""
                })
            
        
        self.views = [view, stat]
        
    
    def __parse_content(self):
        
        url = ""
        meta_item_value = ""
         
        logger.debug("__parse_content start")   
        if use_forbidden_url(self.content):
            url = settings.FORBIDDEN_STREAM_URL
        elif self.content.videopath:
            url = self.content.videopath.rstrip('/') + "/" + self.content.src
            meta_item_value = self.content.videopath.rstrip('/') + "/"
        else:
            url = self.content.src
        
        logger.debug("__parse_content url %s " % url)
        
        media = {
             "http://advene.liris.cnrs.fr/ns/frame_of_reference/ms" : "o=0",
             "id" : self.content.iri_id,
             "url" : url,
             "unit" : "ms",
             "origin" : "0",
             "meta": {
                 "dc:creator" : "",
                 "dc:created" : self.content.creation_date.isoformat(),
                 "dc:contributor" : "",
                 "dc:modified" : self.content.update_date.isoformat(),
                 "dc:creator.contents" : "",
                 "dc:title" : self.content.title,
                 "dc:description" : self.content.description,
                 "dc:duration" : self.content.get_duration(),
                 "item": {
                     "name" : "streamer",
                     "value": meta_item_value,
                 },
             }
        }
        
        self.medias = [media]
        
    
    def __parse_segments(self):
        
        self.annotations = []
        
        for seg in self.segments:
            
            segment_tags = []
            for tag in parse_tag_input(seg.tags):
                if not self.tags.has_key(tag):
                    new_tag = {
                        "meta": {
                            "dc:contributor": "IRI",
                            "dc:created": seg.date,
                            "dc:title": tag,
                            "dc:modified": seg.date,
                            "dc:creator": "IRI"
                        },
                        "id": unicode(uuid.uuid1())
                    }
                    self.tags[tag] = new_tag
                segment_tags.append({'id-ref': self.tags[tag]['id']})
            
            segment = {
                'begin': seg.start_ts,
                'end': seg.start_ts + seg.duration,
                'tags': seg.tags,
                'id': seg.element_id,
                'color': "%s" % self.default_color,
                'media': self.content.iri_id,
                'content': {
                    'mimetype': 'application/x-ldt-structured',
                    'description': seg.abstract,
                    'img': {
                        'src': ''
                    },
                    'title': seg.title,
                    'color': self.default_color,
                    'polemics': [ ],
                    'audio': {
                        'mimetype': 'audio/mp3',
                        'src': seg.audio_src,
                        'href': seg.audio_href
                    }
                
                },
                'meta': {
                         "dc:creator": seg.author,
                         "dc:contributor": seg.author,
                         "dc:created": seg.date,
                         "dc:modified": seg.date,
                         "id-ref": seg.cutting_id,
                         "project": seg.project_id
                },
                'tags': segment_tags                       
            }
            
            self.annotations.append(segment)
    
    def serialize_to_cinelab(self):
        
        logger.debug("serialize_to_cinelab start")
        if not self.segments:
            return None
        
        self.__parse_content()
        logger.debug("serialize_to_cinelab parse content done")
        self.__parse_segments()
        logger.debug("serialize_to_cinelab parse segments done")
        self.__parse_views()
        logger.debug("serialize_to_cinelab parse views done")
        
        res = {}
        res['views'] = self.views 
        res['tags'] = self.tags.values() if len(self.tags) > 0 else None
        res['lists'] = None
        res['medias'] = self.medias
        res['annotations'] = self.annotations
        res['annotation-types'] = self.annotation_types
        
        logger.debug("serialize_to_cinelab done")
        
        return res
    