/**
 * UpdateMetadataFileAction.java
 * Created on Aug 13, 2008
 * (C) Copyright TANDBERG Television Ltd.
 */
package com.tandbergtv.watchpoint.pmm.action.asset.processing;

import java.io.File;

import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.apache.log4j.Logger;
import org.jbpm.graph.def.ActionHandler;
import org.jbpm.graph.exe.ExecutionContext;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.tandbergtv.watchpoint.pmm.util.XMLUtility;

/**
 * @author Vlada Jakobac
 *
 */
public class UpdateMetadataFileAction implements ActionHandler {

	private static final long serialVersionUID = 1L;
	public static String COMBINED_VIDEO = "combinedVideoPath";
	public static String METADATA = "metadataFilePath";
	private static final String FILE_SIZE_XPATH = "//App_Data[@Name='Content_FileSize']";
	private static final String CHECKSUM_XPATH = "//App_Data[@Name='Content_CheckSum']";
	private static final String APP_DATA_VALUE = "Value";
	private static final Logger logger = Logger.getLogger(UpdateMetadataFileAction.class);
	private static final String ASSET_CLASS_XPATH = "//Asset/Asset/Metadata/AMS";
	private static final String ASSET_CLASS = "Asset_Class";

	private void setAttributeValue (String expression, String attribute, Document document, String value){	
		try {
			Node node = (Node) XPathFactory.newInstance().newXPath().evaluate(expression, document, XPathConstants.NODE);
			if (node != null)
				node.getAttributes().getNamedItem(attribute).setTextContent(value);
		} catch (XPathExpressionException e) {
			throw new RuntimeException();
		}
	}
	
	private void setNewFileSize(Document document, String value){
		setAttributeValue(FILE_SIZE_XPATH, APP_DATA_VALUE, document, value);
	}
	
	private void setNewChecksum(Document document, String value){
		setAttributeValue(CHECKSUM_XPATH, APP_DATA_VALUE, document, value);
	}
	
	/* (non-Javadoc)
	 * @see org.jbpm.graph.def.ActionHandler#execute(org.jbpm.graph.exe.ExecutionContext)
	 */
	public void execute(ExecutionContext ec) throws Exception {
		String checksum = ec.getVariable("checksum").toString();
		String fileSize = ec.getVariable("fileSize").toString();
		logger.debug("new fileSize from execution context =" + fileSize);
		
		/* Load the metadata file */
		String metadataFile = ec.getVariable(METADATA).toString();
		Document document = XMLUtility.loadXMLDocument(metadataFile);
		
		NodeList nodes = (NodeList)XPathFactory.newInstance().newXPath().evaluate(ASSET_CLASS_XPATH, document, XPathConstants.NODESET);
		
		for (int i = 0; i < nodes.getLength(); i++){
			Node node = nodes.item(i);
			if (node.getAttributes().getNamedItem(ASSET_CLASS).getTextContent().equals("movie")){
				logger.debug("current fileSize, checksum from document =" + getFileSize(document) + ", " + getChecksum(document));		
				setNewFileSize(document, fileSize);		
				setNewChecksum(document, checksum);
				logger.debug("new fileSize, checksum from document =" + getFileSize(document) + ", " + getChecksum(document));
				break;
			}			
		}	
		//persist the changes to the file
		File xmlFile = new File(metadataFile);
		XMLUtility.saveXMLDocument(document, xmlFile);
		logger.info("Metadata file " + metadataFile + " has been updated with the new values for fileSize and checksum: " +
				fileSize + ", " + checksum);
		 
	}
	
	
	private String getFileSize(Document document){
		return getAttributeValue(FILE_SIZE_XPATH, APP_DATA_VALUE, document);
	}
	
	private String getChecksum(Document document){
		return getAttributeValue(CHECKSUM_XPATH, APP_DATA_VALUE, document);
	}
	

	private String getAttributeValue (String expression, String attribute, Document document){	
		try {
			Node node = (Node) XPathFactory.newInstance().newXPath().evaluate(expression, document, XPathConstants.NODE);
			if (node != null)
				return node.getAttributes().getNamedItem(attribute).getTextContent();
		} catch (XPathExpressionException e) {
			throw new RuntimeException();
		}
		
		return null;
	}
	
	
	
}
