/**
 * FileAsset.java
 * Created Feb 27, 2009
 * Copyright (c) Tandberg Television 2009
 */
package com.tandbergtv.metadata.test.file;

import static com.tandbergtv.metadatamanager.model.FieldName.FILE_NAME;
import static com.tandbergtv.metadatamanager.model.FieldName.FILE_URL;
import static com.tandbergtv.metadatamanager.model.FieldName.MIME_TYPE;
import static com.tandbergtv.metadatamanager.model.FieldName.RESOLUTION;
import static com.tandbergtv.metadatamanager.model.FieldName.SIZE;
import static org.springframework.transaction.TransactionDefinition.PROPAGATION_REQUIRED;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Properties;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.w3c.dom.Document;

import com.sun.org.apache.xml.internal.serialize.OutputFormat;
import com.sun.org.apache.xml.internal.serialize.XMLSerializer;
import com.tandbergtv.metadata.test.search.AssetSearch;
import com.tandbergtv.metadatamanager.ITTVDataModelHandler;
import com.tandbergtv.metadatamanager.JPFActivator;
import com.tandbergtv.metadatamanager.conf.SpecificationBuilder;
import com.tandbergtv.metadatamanager.factoryImpl.SpecHandlerFactory;
import com.tandbergtv.metadatamanager.model.Asset;
import com.tandbergtv.metadatamanager.model.Field;
import com.tandbergtv.metadatamanager.model.File;
import com.tandbergtv.metadatamanager.model.FileType;
import com.tandbergtv.metadatamanager.model.Group;
import com.tandbergtv.metadatamanager.model.Relation;
import com.tandbergtv.metadatamanager.search.AssetSearchService;
import com.tandbergtv.metadatamanager.spec.IIdentifier;
import com.tandbergtv.metadatamanager.spec.ISpecHandler;
import com.tandbergtv.metadatamanager.specimpl.cl1_1.CL1_1_Identifier;
import com.tandbergtv.metadatamanager.specimpl.ttv.TTVId;
import com.tandbergtv.metadatamanager.util.AssetUtil;
import com.tandbergtv.metadatamanager.util.Binder;
/**
 * @author Sahil Verma
 */
public class FileAsset {
	private ApplicationContext context;
	protected AssetSearchService searchService;
	private static final Logger logger = Logger.getLogger(AssetSearch.class);
	
	FileAsset() {
		
		this.context = new ClassPathXmlApplicationContext(
			new String[] { 
					"MetadataBeansContext.xml",
					"MetadataManagerDBContext.xml",
					"file:tests/DataSource_UnitTest.xml" });
		searchService = (AssetSearchService) context.getBean("assetSearch");
		
		startJPF(this.context);
	}
	
	private void startJPF(ApplicationContext context) {
		Properties properties = new Properties();
		String installFolder = "/opt/tandbergtv/cms/plugins";

		properties.put("org.java.plugin.boot.pluginsRepositories", installFolder);
		
		JPFActivator activator = new JPFActivator();
		activator.start(properties);
		
		SpecificationBuilder builder = new SpecificationBuilder(activator.getPluginManager(), context);
		
		builder.buildSpecifications();
	}
	
	void print(Asset asset) {
		logger.info("Asset " + asset);
		
		for (Relation relation : asset.getRelations()) {
			logger.info("\tRelation " + relation);
			Asset child = relation.getTargetAsset();
		
			child = new AssetUtil().unWrap(child);
			print(child);
			
			if (child instanceof File) {
				File f = File.class.cast(child);
				logger.info("URL is " + f.getURL());
				logger.info("Size is " + f.getSize());
			}
		}
	}
	
	void asset(long id) throws Exception {
		Asset asset = getDataModelHandler().getAsset(new TTVId(id));
		
		print(asset);
	}
	
	long create(String url) throws Exception {
		java.io.File file = new java.io.File(url);
		DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
		Document source = builder.parse(file);
		ISpecHandler sh = getSpecHandler("CL1_1");
		List<IIdentifier> ids = sh.put(source, null, "init", null);
		IIdentifier id = ids.get(0).getAsset().getTTVId(); 
		
		logger.info("Created " + id);
		System.out.println("Created " + id);
		
		return TTVId.class.cast(id).getId();
	}
	
	void delete(long id) throws Exception {
		getDataModelHandler().delete(new Group());
	}
	
	void dom(long id, String version) throws Exception {
//		ISpecHandler sh = (ISpecHandler) context.getBean("CL1_1_SpecHandler");
//		Document document = sh.get(createIdentifier());
		ITTVDataModelHandler handler = getDataModelHandler(); 
		Asset asset = handler.getAsset(new TTVId(id), version);
		Document document = new Binder().bind(asset);
		
		print(id, version, document);
	}

	protected void print(long id, String version, Document document) {
		try {
		OutputFormat format = new OutputFormat(document);
		format.setIndenting(true);
		java.io.File outFile = new java.io.File("tests/output/FileAsset_output_" + id + version+ ".xml");
		XMLSerializer serializer = new XMLSerializer(new FileOutputStream(
				outFile, false), format);
		serializer.serialize(document);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	void cablalabsdom(long id) throws Exception {
		ISpecHandler sh = getSpecHandler("CL1_1");
		Document document = sh.get(new TTVId(id));
		
		TransformerFactory.newInstance().newTransformer().transform(
			new DOMSource(document), new StreamResult(new java.io.File("/tmp/" + id + ".xml")));
		
		logger.info("Wrote file /tmp/" + id + ".xml");
	}
	
	void file(long id, long childid) throws Exception {
		ITTVDataModelHandler handler = getDataModelHandler(); 
		Asset asset = handler.getAsset(new TTVId(id));
		
		
		for (Relation childRelation : asset.getRelations()) {
			Asset child = childRelation.getTargetAsset();
			if (child.getId() == childid) {
				Asset file = createfile();
		
				child.addChild(file);
				break;
			}
		}
		
		
		handler.saveAsset(asset, true);
		
		logger.info("File created");
	}
	
	void update(long id, long childid) throws Exception {
		ITTVDataModelHandler handler = getDataModelHandler(); 
		Asset asset = handler.getAsset(new TTVId(id));
		
		
		for (Relation childRelation : asset.getRelations()) {
			Asset child = childRelation.getTargetAsset();
			if (child.getId() == childid) {
				List<Field> titleFields = child.getFields();
				for(Field titleField: titleFields){
					if("/tns:Fields/tns:CreationInfo/tns:Studio/tns:DisplayName".equals(titleField.getTtvXPath())){
						titleField.setValue("Mao Studio");
					}
				}
				break;
			}
		}
		
		
		handler.saveAsset(asset, true);
		
		System.out.println("Done updating");
	}
	File createfile() {
		File file = new File();
		
//		file.setType(ItemType.VIDEO);
		file.setFileType(FileType.ORIGINAL);
		
		file.addField(new Field(FILE_URL.toString(), "rtsp://rtsp2.youtube.com/ChoLENy73wIaEQlbwqbpvT6ZzhMYDSANFEgGDA==/0/0/0/video.3gp"));
		file.addField(new Field(FILE_NAME.toString(), "ChoLENy73wIaEQlbwqbpvT6ZzhMYDSANFEgGDA==/0/0/0/video.3gp"));
		file.addField(new Field(MIME_TYPE.toString(), "video/3gpp"));
		file.addField(new Field(RESOLUTION.toString(), "1920.0x1080.0"));
		file.addField(new Field(SIZE.toString(), "26010364"));
		
		return file;
	}
	
	ITTVDataModelHandler getDataModelHandler() {
		ITTVDataModelHandler handler = (ITTVDataModelHandler) context.getBean("TTVSpecHandler");
		
		return handler;
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			logger.info("T-1 seconds and counting...");
			
			FileAsset t = new FileAsset();
			
			PlatformTransactionManager txmgr = 
				(PlatformTransactionManager) t.context.getBean("transactionManager");
			TransactionStatus status = 
				txmgr.getTransaction(new DefaultTransactionDefinition(PROPAGATION_REQUIRED));
			
//			long id = t.create("tests/com/tandbergtv/spec/sampleInput/cl1_1-sample_small_2.xml");
//			t.asset(227L);
//			t.dom(227L);
//			t.file(1, 3);
			t.dao(1, "." +1);
//			t.dom(1, "." +1);
//			t.dom(1, "." +2);
//			t.dom(1, "." +1);
//			t.update(1, 2);
			//t.delete(212L);
			
			txmgr.commit(status);
			System.out.println("FileAsset done!");
		} catch (Throwable e) {
			logger.error("Damn!", e);
			e.printStackTrace();
		}
	}
	
	
	protected IIdentifier createIdentifier(){
		ISpecHandler sh = getSpecHandler("CL1_1");
		
		CL1_1_Identifier id = (CL1_1_Identifier) sh.getIdentifier();

		id.setAssetId("UNVA2001081701003000");
		id.setProviderId("indemand.com");
		return id;
	}
	
	void dao(long id, String version) throws Exception {

		ITTVDataModelHandler handler = getDataModelHandler(); 
		Asset asset = handler.getAsset(new TTVId(id), version);

//		System.out.println("asset is:" + asset);
	}
	
	void rollback(long id, String version) throws Exception {

		ISpecHandler sh = getSpecHandler("CL1_1");
		Document doc = sh.rollBackToRevision(new TTVId(id), version);

		print(id, "rollbackTo" + version,doc);
	}
	
	private ISpecHandler getSpecHandler(String specName) {
		ISpecHandler handler = SpecHandlerFactory.getInstance(specName);
		return handler;
	}
}
