from ldt.ldt_utils.models import Project
from piston.handler import BaseHandler
from piston.utils import rc, require_extended
from ldt.ldt_utils.utils import LdtAnnotation
import logging #@UnresolvedImport
import lxml.etree


class ProjectHandler(BaseHandler):
    allowed_methods = ('GET', 'PUT',)
    model = Project   

    def read(self, request, project_id):
        """
        returns a single project
        """
        return Project.objects.get(ldt_id=project_id)
    
    @require_extended
    def update(self, request, project_id):
        """
        This method is called when a PUT request is sent to http://<plateform_location>/api/ldt/projects/<project_id>.format. The
        request should contain a content-type header whose value can be either "application/json" or "text/xml" and a valid utf-8
        encoded JSON or XML file.
            <project_id> is the ldt_id field of the project. If <projet_id> does not match any project on the platform, a 410 ("Gone")
            error will be returned.
            <format> is the format of the data sent back by the server. It can be 'json', 'yaml', 'xml' or 'pickle'.
        
        If the submitted file is not valid or refers to a media that is not contained in the project, a 500  ("Bad Request")
        error will be returned. If the "type" field of an annotation matches an already existing cutting, it will be added to that 
        cutting. Otherwise, a new cutting will be added (as well as a new ensemble if needed). Several annotations can be added at 
        the same time if the submitted file contains multiple annotations. The server returns a 201 ("Created") code if annotations have
        been added successfully.   
        
        Example :
        
        Remark : Both files below contain the minimum necessary fields and attributes for the handler to work. If one field or attribute is
        missing (e.g. author, or date) during submission, an error will occur.
        
        A platform is reachable at http://localhost/. It contains a project with ID a0593b58-f258-11df-80e1-00145ea4a2be. This project has
        a content milosforman_amadeus, which has a cutting Salieri. The following JSON file exists in the current directory :
    
        {
            "annotations": [
                {
                    "type": "New cutting name",
                    "media": "milosforman_amadeus",
                    "begin": 50000,
                    "end": 900000,
                    "content": {
                        "data": "new annotation"
                    },
                    "tags": [ "json" ]
                },
                {
                    "type": "Salieri",
                    "media": "milosforman_amadeus",
                    "begin": 700000,
                    "end": 1200000,
                    "content": {
                        "data": "Annotation about Salieri"
                    },
                    "tags": [ "xml", "test", "blop" ]
                }
            ],
            
            "meta": {
                "creator": "John Doe",
                "created": "2011-09-10T09:12:58"
            }
        }
            
        If we send a PUT request with curl :    
        $curl -X PUT http://localhost/api/ldt/projects/a0593b58-f258-11df-80e1-00145ea4a2be.json -d @example.JSON -H  "content-type:application/json"
        A new cutting titled "New cutting name" will be created with the first annotation inside, and the annotation "Annotation about Salieri"
        will be added to the Salieri cutting. 
        
        Similar results can be obtained using the following xml file :
        
        <iri>
          <annotations>
            <content id="milosforman_amadeus">
              <ensemble>
                <decoupage>
                  <title>New cutting name</title>
                  <abstract/>
                  <elements>
                    <element begin="50000" dur="895000" date="2011-09-10T09:12:58" author="John Doe">
                      <title>new annotation</title>
                      <abstract/>
                      <audio source=""/>
                      <tags>
                        <tag>json</tag>
                      </tags>
                    </element>            
                  </elements>
                </decoupage>
                <decoupage >
                  <title>Salieri</title>
                  <abstract/>
                  <elements>
                    <element begin="700000" dur="500000" date="2011-09-10T09:12:58" author="John Doe">
                      <title>Annotation about Salieri</title>
                      <abstract/>
                      <audio source=""/>
                      <tags>
                          <tag>xml</tag>
                          <tag>test</tag>
                          <tag>blop</tag>
                      </tags>
                    </element>            
                  </elements>
                </decoupage>
            </ensemble>
           </content>
          </annotations>
        </iri>
        
        and the command :
        
        $curl -X PUT http://localhost/api/ldt/projects/a0593b58-f258-11df-80e1-00145ea4a2be.json -d @example.LDT -H  "content-type:text/xml"
          
        """    
        
        try:
            project = Project.objects.get(ldt_id=project_id)
        except Project.DoesNotExist:
            return rc.NOT_HERE 

        adder = LdtAnnotation(project)           
          
        if request.content_type == 'application/json':
            
            logging.debug("request json " + repr(request.data))       

            meta = request.data['meta']
            author = meta['creator']
            date = meta['created']
            new_annotations = request.data['annotations']

            for a in new_annotations:
                dur = str(a['end'] - a['begin'])
                begin = str(a['begin'])
                if not adder.add(a['media'], a['type'], a['content']['data'], '', a['tags'], begin, dur, author, date):
                    return rc.BAD_REQUEST

            return rc.ALL_OK
            
        elif request.content_type == "text/xml":        
            logging.debug("request xml" + repr(request))
            
            ldtdoc = lxml.etree.fromstring(request.raw_post_data) 
            
            for content in ldtdoc.xpath('/iri/annotations/content'):
                content_id = content.get('id')
                
                for decoupage in content.xpath('ensemble/decoupage'):
                    dec_title = decoupage.xpath('title')[0].text
                    author = decoupage.get('author')                                            
                    
                    for element in decoupage.xpath('elements/element'):
                        begin = element.get('begin')
                        dur = element.get('dur')
                        date = element.get('date')
                        title = element.xpath('title')[0].text
                        abstract = element.xpath('abstract')[0].text
                        tags = []
                        for tag in element.xpath('tags/tag'):
                            tags.append(tag.text)
                            
                        if not adder.add(content_id, dec_title, title, abstract, tags, begin, dur, author, date):
                            return rc.BAD_REQUEST
        
            return rc.ALL_OK
        
        return rc.NOT_IMPLEMENTED
