package com.tandbergtv.watchpoint.pmm.communication.handlers;

import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.tandbergtv.watchpoint.communication.Util;
import com.tandbergtv.watchpoint.pmm.communication.MessageHandler;
import com.tandbergtv.watchpoint.pmm.core.IPMMService;
import com.tandbergtv.watchpoint.pmm.entities.Planner;
import com.tandbergtv.watchpoint.pmm.entities.Title;
import com.tandbergtv.watchpoint.pmm.schedule.bind.ScheduleUnmarshaller;
import com.tandbergtv.watchpoint.pmm.title.bind.TitleUnmarshaller;
import com.tandbergtv.workflow.core.service.ServiceRegistry;
import com.tandbergtv.workflow.message.WorkflowMessage;
import com.tandbergtv.workflow.message.WorkflowMessage.MessageType;


/**
 * Message Handler for "Ingest Schedule list / Program list" message.
 * 
 * @author Raj Prakash
 */
public class IngestScheduleProgramListMessageHandler implements MessageHandler {

	private static final String FILE_PATH = "filePath";
	private static final String FILE_TYPE = "fileType";
	private static final String FILE_TYPE_PROGRAMLIST = "Program List";
	private static final String FILE_TYPE_PLANNER = "Planner";
	
	private static final String XPATH_PLANNER = "/planners/planner";
	private static final String XPATH_TITLE = "/titles/title";
	
	/* (non-Javadoc)
	 * @see com.tandbergtv.watchpoint.pmm.communication.MessageHandler#handleMessage(com.tandbergtv.workflow.message.WorkflowMessage)
	 */
	public WorkflowMessage handleMessage(WorkflowMessage message) throws Exception {

		Util.validateRequired(message, FILE_PATH, FILE_TYPE);
		
		String fileType = Util.getStringValueTrimmed(message, FILE_TYPE);
		String filePath = Util.getStringValueTrimmed(message, FILE_PATH);
		
		IPMMService pmmService = ServiceRegistry.getDefault().lookup(IPMMService.class);
		
		if(fileType.equals(FILE_TYPE_PROGRAMLIST)) {
			Collection<Title> titles = parseTitles(filePath);			
			pmmService.programListArrived(titles);
		} else if(fileType.equals(FILE_TYPE_PLANNER)) {
			Collection<Planner> planners = parsePlanners(filePath);
			pmmService.plannersArrived(planners);
		}

		return new WorkflowMessage(message.getMessageUID(), message.getKey(), MessageType.ack);
	}
	
	/**
	 * @param filePath
	 * @return
	 */
	private Collection<Title> parseTitles(String filePath) throws Exception {
		List<Title> titles = new ArrayList<Title>();

		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = factory.newDocumentBuilder();
		Document doc = docBuilder.parse(new File(filePath));

		XPath xPath = XPathFactory.newInstance().newXPath();
		NodeList nodeSet = (NodeList) xPath.evaluate(XPATH_TITLE, doc,
				XPathConstants.NODESET);

		if (nodeSet != null) {
			for (int i = 0; i < nodeSet.getLength(); ++i) {
				Node node = nodeSet.item(i);
				titles.add(TitleUnmarshaller.newInstance().unmarshal(node));
			}
		}

		return titles;
	}

	/*
	 * Parses the xml planners file to a list of planner objects. 
	 */
	private List<Planner> parsePlanners(String filePath) throws Exception {
		List<Planner> planners = new ArrayList<Planner>();
		
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder docBuilder = factory.newDocumentBuilder();
		Document doc = docBuilder.parse(new File(filePath));

		XPath xPath = XPathFactory.newInstance().newXPath();
		NodeList nodeSet = (NodeList) xPath.evaluate(XPATH_PLANNER, doc, XPathConstants.NODESET);
		
		if(nodeSet != null) {
			for(int i=0; i<nodeSet.getLength(); ++i) {
				Node node = nodeSet.item(i);
				Planner planner = (Planner) ScheduleUnmarshaller.newInstance().unmarshal(node);
				planners.add(planner);
			}
		}

		return planners;
	}

}
