package com.ttv.acs.stub.adi;

import java.io.File;
import java.io.FileInputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathFactory;

import org.apache.log4j.Logger;
import org.apache.xpath.XPathAPI;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;


public class ADIParseUtil {

	private final static Logger log = Logger.getLogger(ADIParseUtil.class);
	private final static XPath xpath = XPathFactory.newInstance().newXPath();

	/**
	 * Read an ADI.XML file up from the file system and return an ADI object
	 * 
	 * @param file
	 * @return
	 * @throws Exception
	 */
	public static ADI parseFile(File xmlFile, File dtdFile) throws Exception {
		log.debug("Begin parseFile(" + xmlFile);
		ADI adi = new ADI();

		DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
		documentBuilderFactory.setNamespaceAware(true);
		DocumentBuilder builder;
		try {
			builder = documentBuilderFactory.newDocumentBuilder();
			builder.setEntityResolver(new ADIDTDEntityResolver(dtdFile));

			Document adiXML = builder.parse(xmlFile);

			String providerid = xpath.evaluate("/ADI/Metadata/AMS/@Provider_ID", adiXML);
			String assetID = xpath.evaluate("/ADI/Metadata/AMS/@Asset_ID", adiXML);

			Metadata meta = new Metadata(providerid, assetID);

			adi.setMetadata(meta);

			List<Asset> assets = new ArrayList<Asset>();
			adi.setAssets(assets);
			NodeList contents = XPathAPI.selectNodeList(adiXML.getDocumentElement().getFirstChild(), "//Content[string-length(@Value)>0]");
			if (contents != null) {
				for (int i = 0; i < contents.getLength(); i++) {
					Node assetNode = contents.item(i).getParentNode();
					String checksum = xpath.evaluate("Metadata/App_Data[@Name='Content_CheckSum']/@Value", assetNode);
					String content = xpath.evaluate("Content/@Value", assetNode);
					Asset asset = new Asset(content, checksum);
					assets.add(asset);
				}
			}
		} catch (Exception e) {
			log.error("Fail to parse ADI.XML", e);
			throw e;
		}
		return adi;
	}

	public static class ADIDTDEntityResolver implements EntityResolver {
		File dtdFile;
		
		public ADIDTDEntityResolver(File dtdFile) {
			super();
			this.dtdFile = dtdFile;
		}

		public InputSource resolveEntity(String publicId, String systemId) throws SAXException, java.io.IOException {
			FileInputStream s = new FileInputStream(this.dtdFile);
			return new InputSource(s);
		}
	}

	public static ADI stubADI() {
		Asset movieAsset = new Asset("ModernGirlsGuidetoLife.mpg", "testchecksum");
		Asset adAsset = new Asset("neutrogena.mpg", "testchecksum");
		List<Asset> assets = new ArrayList<Asset>();
		assets.add(movieAsset);
		assets.add(adAsset);
		ADI stubADI = new ADI(assets, new Metadata("n2bb.com", "CBMV0001000000000001"));

		return stubADI;
	}
}
