package fr.iri.thd.sonyengine.web;

import java.io.IOException;
import java.io.StringReader;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContext;
import javax.ws.rs.Consumes;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import fr.iri.thd.sonyengine.core.DataAccessor;
import fr.iri.thd.sonyengine.core.DbEnv;
import fr.iri.thd.sonyengine.core.EngineAccessor;
import fr.iri.thd.sonyengine.core.SonyengineException;
import fr.iri.thd.sonyengine.core.Tag;

@Path ("tag")
public class TagResource {
	
    @Path("add/{id}/{movieFragment}")
    @POST
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Tag add(@PathParam("id") String tagName, @PathParam("movieFragment") String movieSegmentRef, @Context ServletContext context) {
    	return this.add(tagName, movieSegmentRef, Boolean.TRUE, context);
    }

	
    
    @Path("add/{id}/{movieFragment}/{retrain}")
    @POST
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public Tag add(@PathParam("id") String tagName, @PathParam("movieFragment") String movieSegmentRef, @PathParam("retrain") Boolean retrain, @Context ServletContext context) {
        EngineAccessor.getInstance().addTag(tagName, movieSegmentRef);

    	DbEnv dbenv = (DbEnv)context.getAttribute(ServletContainer.DB_ENV_ATTRIBUTE);
		
		DataAccessor da = new DataAccessor(dbenv.getEntityStore());
		
		
		Tag tag = new Tag(tagName, movieSegmentRef);
		da.tagById.put(tag);
		dbenv.sync();

		if(retrain != null && retrain.booleanValue())
		    EngineAccessor.getInstance().train(false);

		return tag;	
		
    }
    
    @Path("add")
    @POST
    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public List<Tag> add(@FormParam("xml") String xmldocstr, @FormParam("retrain") Boolean retrain, @Context ServletContext context) throws SonyengineException {
    	
    	DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
    	InputSource source = new InputSource(new StringReader(xmldocstr));
    	Document doc = null;
		try {
			doc = factory.newDocumentBuilder().parse(source);
		} catch (SAXException e) {
			e.printStackTrace();
			throw new SonyengineException("Error when parsing xml with string " + xmldocstr, e);
		} catch (IOException e) {
			e.printStackTrace();
			throw new SonyengineException("Error when parsing xml with string " + xmldocstr, e);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
			throw new SonyengineException("Error when parsing xml with string " + xmldocstr, e);
		}
    	DbEnv dbenv = (DbEnv)context.getAttribute(ServletContainer.DB_ENV_ATTRIBUTE);		
		DataAccessor da = new DataAccessor(dbenv.getEntityStore());

    	
    	NodeList tags = doc.getElementsByTagName("tag");
    	
    	List<Tag> list = new ArrayList<Tag>();
    	
    	for(int i = 0; i<tags.getLength(); i++)
    	{
    		Element node = (Element)tags.item(i);
    		String segment = node.getAttribute("segment");
    		String name = node.getAttribute("name");
    		Tag tag = new Tag(name, segment);
    		EngineAccessor.getInstance().addTag(name, segment);
    		da.tagById.put(tag);
    		list.add(tag);
    	}

		dbenv.sync();
    	
		if(retrain != null && retrain.booleanValue())
		    EngineAccessor.getInstance().train(false);
    	
    	return list;
    }

}


