from ldt.ldt_utils.contentindexer import add_segment
from ldt.ldt_utils.models import Project, Content
from ldt.ldt_utils.utils import LdtAnnotation
from ldt.security import protect_models, unprotect_models
from tastypie import fields
from tastypie.authorization import Authorization
from tastypie.exceptions import NotFound, BadRequest
from tastypie.resources import Resource


class AnnotationObject(object):
    def __init__(self, id="", project = "", type = "", type_title = "", ensemble="", media = "", begin = 0, end = 0, content = {"title":"", "description":""}, tags = [], meta = {"creator":"","created":""}):  # @ReservedAssignment
        self.id = id
        self.project = project
        self.type = type
        self.type_title = type_title
        self.ensemble = ensemble
        self.media = media
        self.begin = begin
        self.end = end
        self.content = content
        self.tags = tags
        self.meta = meta
    
class AnnotationResource(Resource):
    # For the moment, these attributes are useless. We just prepare relations to AnnotationObject
    id = fields.CharField(attribute = 'id')
    project = fields.CharField(attribute = 'project')
    type = fields.CharField(attribute = 'type')
    type_title = fields.CharField(attribute = 'type_title')
    media = fields.CharField(attribute = 'media')
    begin = fields.IntegerField(attribute = 'begin')
    end = fields.IntegerField(attribute = 'end')
    content = fields.DictField(attribute = 'content')
    tags = fields.ListField(attribute = 'tags')
    meta = fields.DictField(attribute = 'meta')
    
    class Meta:
        allowed_methods = ['post']
        resource_name = 'annotations'
        object_class = AnnotationObject
        authorization = Authorization()
        # always_return_data = True because we want the api returns the data with the updated ids
        always_return_data = True
        include_resource_uri = False
    
    def obj_delete_list(self, bundle, **kwargs):
        return True
    
    def obj_create(self, bundle, **kwargs):
        # Here the a has the datas for only one annotation. Tastypie's post allows only one resource addition
        a = bundle.data
        project_id = ""
        if a.has_key('project') :
            project_id = a["project"]
        if project_id and project_id != "" :
            try:
                project = Project.objects.get(ldt_id=project_id)
            except Project.DoesNotExist:
                raise NotFound("Project not found. project_id = " + project_id)
        else :
            # If the project's is not defined, we get or create the content's front project.
            iri_id = a["media"]
            try:
                content = Content.objects.get(iri_id=iri_id)
            except Content.DoesNotExist:
                raise NotFound("Content not found. iri_id = " + iri_id)
            project = content.get_or_create_front_project()
            a[u"project"] = project.ldt_id
        
        adder = LdtAnnotation(project)
        unprotect_models() # Allows anonymous user to modify models in this request only
        
        dur = str(a['end'] - a['begin'])
        begin = str(a['begin'])
        # We test if the annotation has audio node
        audio_src = ""
        audio_href = ""
        if a['content'].has_key('audio') :
            if a['content']['audio'].has_key('src') :
                audio_src = a['content']['audio']['src']
            if a['content']['audio'].has_key('href') :
                audio_href = a['content']['audio']['href']
        meta = a['meta']
        author = meta['creator']
        date = meta['created']
        #                                    add(media,      cutting_id, cutting_title,  title,                 text,                        tags_list, begin, dur, author, date
        type_id, new_id, ensemble_id = adder.add(a['media'], a['type'], a['type_title'], a['content']['title'], a['content']['description'], a['tags'], begin, dur, author, date, None, "2194379", audio_src, audio_href)
        if not new_id:
            protect_models()
            raise BadRequest
                        
        content = project.contents.get(iri_id=a['media'])
        
        # We update the ids
        a['type'] = type_id
        a['ensemble'] = ensemble_id
        a['id'] = new_id
        if not a['content'].has_key('audio') :
            a['content']['audio'] = {'src':audio_src, 'href':audio_href}
        
        #add segment
        add_segment({
            "project" : project,
            "content" : content,
            "ensemble_id" : ensemble_id,
            "cutting_id" :  a['type'],            
            "element_id" : new_id,
            "title" : a['content']['title'],
            "abstract" : a['content']['description'],
            "tags" : ",".join(a['tags']),
            "start_ts" : begin,
            "duration" :  dur,
            "author" : author,
            "date" : date, 
            "audio_src" : audio_src,            
            "audio_href" : audio_href,
            "polemics": adder.get_polemic_syntax(a['content']['title'])
        })
            
        # We save the added annotation and reprotect the contents and projects
        adder.save(must_reindex=False)
        protect_models()
        # We update the AnnotationObject for the returned datas to be correct.
        bundle.obj = AnnotationObject(id = a["id"], project = a["project"], type = a["type"], type_title = a["type_title"], ensemble=a['ensemble'], media = a["media"], begin = a["begin"], end = a["end"], content = a['content'], tags = a['tags'], meta = a['meta'])
        return bundle
    
    def get_resource_uri(self, bundle_or_obj=None, url_name='api_dispatch_list'):
        return ''

    