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.MovieFragment;
import fr.iri.thd.sonyengine.core.SonyengineException;

@Path ("segment")
public class MovieFragmentResource {

	private MovieFragment create(String id, boolean retrain, ServletContext context) {

		EngineAccessor.getInstance().createMovieFragment(id);
		
		DbEnv dbenv = (DbEnv)context.getAttribute(ServletContainer.DB_ENV_ATTRIBUTE);
		
		DataAccessor da = new DataAccessor(dbenv.getEntityStore());
		
		MovieFragment fragment = new MovieFragment(id);
		da.movieFragmentById.put(fragment);
		dbenv.sync();
		
		if(retrain)
		    EngineAccessor.getInstance().train();
		
		return fragment;
		
	}
	
	@POST
	@Path("create/{id}")
	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public MovieFragment createPath(@PathParam("id") String id, @Context ServletContext context) {
  
		return this.create(id, true, context);
    }

	@POST
	@Path("create/{id}/{retrain}")
	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
    public MovieFragment createPath(@PathParam("id") String id, @PathParam("retrain") Boolean retrain, @Context ServletContext context) {
  
		return this.create(id, (retrain != null && retrain.booleanValue()), context);
    }

	
	@POST
	@Path("create")
	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
    public MovieFragment createForm(@FormParam("id") String id, @FormParam("retrain") Boolean retrain, @Context ServletContext context) {
		return this.create(id, (retrain != null && retrain.booleanValue()), context);		
    }
	
	@POST
	@Path("createall")
	@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public List<MovieFragment> createAll(@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("Exception when parsing " + xmldocstr, e);
		} catch (IOException e) {
			e.printStackTrace();
			throw new SonyengineException("Exception when parsing " + xmldocstr, e);
		} catch (ParserConfigurationException e) {
			e.printStackTrace();
			throw new SonyengineException("Exception when parsing " + xmldocstr, e);
		}
    	DbEnv dbenv = (DbEnv)context.getAttribute(ServletContainer.DB_ENV_ATTRIBUTE);		
		DataAccessor da = new DataAccessor(dbenv.getEntityStore());

    	
    	NodeList tags = doc.getElementsByTagName("segment");
    	
    	List<MovieFragment> list = new ArrayList<MovieFragment>();
    	
    	for(int i = 0; i<tags.getLength(); i++)
    	{
    		Element node = (Element)tags.item(i);
    		String id = node.getAttribute("id");
    		MovieFragment sequence = new MovieFragment(id);
    		EngineAccessor.getInstance().createMovieFragment(id);
    		da.movieFragmentById.put(sequence);
    		list.add(sequence);
    	}

		dbenv.sync();

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

	}
	
	private void clearTags(String id, boolean retrain, ServletContext context) {

	    EngineAccessor.getInstance().clearTags(id);
		
		DbEnv dbenv = (DbEnv)context.getAttribute(ServletContainer.DB_ENV_ATTRIBUTE);
		
		DataAccessor da = new DataAccessor(dbenv.getEntityStore());
		da.tagBySegment.delete(id);
		dbenv.sync();
		
		if(retrain)
		    EngineAccessor.getInstance().train();
	}

	@POST
	@Path("cleartags/{id}")
	@Produces(MediaType.TEXT_PLAIN)
	public String clearTagsPath(@PathParam("id") String id, @Context ServletContext context) {
		
		this.clearTags(id, true, context);
		return "ok";
	}

	
	@POST
	@Path("cleartags/{id}/{retrain}")
	@Produces(MediaType.TEXT_PLAIN)
	public String clearTagsPath(@PathParam("id") String id, @PathParam("retrain") Boolean retrain, @Context ServletContext context) {
		
		this.clearTags(id, (retrain != null && retrain.booleanValue()), context);
		return "ok";
	}

	@POST
	@Path("cleartags")
	@Produces(MediaType.TEXT_PLAIN)
	@Consumes(MediaType.APPLICATION_FORM_URLENCODED)
	public String clearTagsForm(@FormParam("id") String id, @FormParam("retrain") Boolean retrain, @Context ServletContext context) {
		
		this.clearTags(id, (retrain != null && retrain.booleanValue()), context);
		return "ok";
	}

	
}


