package com.tandbergtv.watchpoint.pmm;

import static org.springframework.transaction.TransactionDefinition.PROPAGATION_REQUIRED;

import java.io.File;
import java.util.Collection;
import java.util.Properties;

import junit.framework.TestCase;

import org.hibernate.Session;
import org.springframework.context.ApplicationContext;
import org.springframework.orm.hibernate3.HibernateTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.tandbergtv.metadatamanager.ITTVDataModelHandler;
import com.tandbergtv.metadatamanager.JPFActivator;
import com.tandbergtv.metadatamanager.model.Asset;
import com.tandbergtv.metadatamanager.model.Field;
import com.tandbergtv.metadatamanager.search.AssetSearchService;
import com.tandbergtv.metadatamanager.specimpl.ttv.TTVId;
import com.tandbergtv.watchpoint.pmm.dao.hibernate.ApplicationContextHelper;
import com.tandbergtv.watchpoint.pmm.dao.hibernate.HibernateContext;
import com.tandbergtv.watchpoint.pmm.entities.Title;
import com.tandbergtv.watchpoint.pmm.title.TitleActivator;
import com.tandbergtv.watchpoint.pmm.title.provider.internal.DefaultTitleSearchStrategy;
import com.tandbergtv.watchpoint.search.Association;
import com.tandbergtv.watchpoint.search.Entity;
import com.tandbergtv.watchpoint.search.Join;
import com.tandbergtv.workflow.driver.search.SearchOperator;
import com.tandbergtv.workflow.driver.search.SearchType;
import com.tandbergtv.workflow.driver.search.SortParameter;
import com.tandbergtv.workflow.driver.search.ValueParameter;
import com.tandbergtv.workflow.util.SearchCriteria;
import com.tandbergtv.workflow.util.SortingOrder;

public class StartupTest extends TestCase {

	private TitleActivator activator;
	private ApplicationContext context;

	private static final String PLUGIN_FOLDER_RELATIVE_PATH = "plugins";
	private static final String JPF_PLUGIN_REPOSITORY_PROPERTY = "org.java.plugin.boot.pluginsRepositories";

	/*
	 * (non-Javadoc)
	 * 
	 * @see junit.framework.TestCase#setUp()
	 */
	@Override
	protected void setUp() throws Exception {
		initializeMetadataManagerBeans();
		initializeTitleServices();
		context = ApplicationContextHelper.getInstance().getContext();

		super.setUp();
	}

	private void initializeMetadataManagerBeans() {
		String[] contextConfigFiles = {
				"MetadataBeansContext.xml",
				"com/tandbergtv/watchpoint/pmm/dao/hibernate/TitleMetadataManagerDBContext.xml",
				"com/tandbergtv/watchpoint/pmm/dao/hibernate/AssetDataSource.xml" };
		new ApplicationContextHelper(contextConfigFiles);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see junit.framework.TestCase#tearDown()
	 */
	@Override
	protected void tearDown() throws Exception {
		activator.stop();
		super.tearDown();
	}

	public void testSessionFactory() {
		HibernateTemplate hibernateTemplate = (HibernateTemplate) context
				.getBean("hibernateTemplate");
		System.out.println("Session factory from hibernate template: "
				+ hibernateTemplate.getSessionFactory().hashCode());

		System.out.println("Session Factory from hibernate context: "
				+ HibernateContext.getContext().getSessionFactory().hashCode());
	}

	private void initializeTitleServices() {
		/* Properties for initializing JPF */
		Properties properties = new Properties();
		String installFolder = "D://opt//tandbergtv//cms";
		File pluginFolder = new File(installFolder, PLUGIN_FOLDER_RELATIVE_PATH);
		properties.put(JPF_PLUGIN_REPOSITORY_PROPERTY, pluginFolder
				.getAbsolutePath());

		/* Start JPF */
		JPFActivator jpf = new JPFActivator();
		jpf.start(properties);

		/* Title and Asset related initialization */
		activator = new TitleActivator();
		activator.setPluginManager(jpf.getPluginManager());
		activator.start();
	}

	public void testRetrievingAsset() {
		AssetSearchService searchService = (AssetSearchService) ApplicationContextHelper
				.getInstance().getContext().getBean("assetSearch");
		SearchCriteria criteria = new SearchCriteria();
		Entity asset = new Entity("asset", Asset.class, "a");
		asset.addParameter(new ValueParameter("root", SearchType.STRING,
				(Object) null));
		criteria.addParameter(asset);
		criteria.setRecordsCount(Integer.MAX_VALUE);

		PlatformTransactionManager txmgr = (PlatformTransactionManager) ApplicationContextHelper
				.getInstance().getContext().getBean("transactionManager");
		TransactionStatus status = txmgr
				.getTransaction(new DefaultTransactionDefinition(
						PROPAGATION_REQUIRED));

		Collection<Asset> assets = searchService.search(criteria);

		for (Asset a : assets) {
			System.out.println(a.toString());
		}

		txmgr.commit(status);
	}

	public void testRetrievingTitle() {
		SearchCriteria criteria = getSearchCriteria();

		DefaultTitleSearchStrategy strategy = new DefaultTitleSearchStrategy();

		PlatformTransactionManager txmgr = (PlatformTransactionManager) ApplicationContextHelper
				.getInstance().getContext().getBean("transactionManager");
		TransactionStatus status = txmgr
				.getTransaction(new DefaultTransactionDefinition(
						PROPAGATION_REQUIRED));

		// Collection<TestTitle> titles = strategy.search(criteria);

//		for (TestTitle t : titles) {
//			System.out.println(t.toString());
//		}
		txmgr.commit(status);
	}

	public void testSavingTitle() {
		ITTVDataModelHandler handler = (ITTVDataModelHandler) ApplicationContextHelper
				.getInstance().getContext().getBean("TTVSpecHandler");
		try {
			PlatformTransactionManager txmgr = (PlatformTransactionManager) ApplicationContextHelper
					.getInstance().getContext().getBean("transactionManager");
			TransactionStatus status = txmgr
					.getTransaction(new DefaultTransactionDefinition(
							PROPAGATION_REQUIRED));

			Asset a = handler.getAsset(new TTVId(46));

			// Session s = HibernateContext.getContext().getCurrentSession();
			// s.beginTransaction();
			// TestTitle t = (TestTitle) s.get(TestTitle.class, 3);

			// Asset a = t.getAsset();
			Field f = a.getFirstField("f1");
			f.setValue("value2");

			// handler.saveAsset(a);

			Title t = new Title();
			t.setAsset(a);
			Session s = HibernateContext.getContext().getCurrentSession();

			/*
			 * Group group = new Group(); group.setType(GroupType.PACKAGE);
			 * group.addField(new Field("f1", "f1")); group.addField(new
			 * Field("f2", "f2"));
			 */

			s.save(t);
			// HibernateTemplate template = (HibernateTemplate)
			// ApplicationContextHelper
			// .getInstance().getContext().getBean("hibernateTemplate");
			// template.save(t);

			System.out.println("Created title: " + t.toString());
			// txmgr.commit(status);
			// s.close();
			s.getTransaction().commit();
		} catch (Exception e) {
			System.out.println(e);
		}
	}

	private SearchCriteria getSearchCriteria() {
		SearchCriteria criteria = new SearchCriteria();
		Entity test = new Entity("testTitle", Title.class, "testtitle");
		// test.addParameter(new SortParameter("id", SortingOrder.ASCENDING));

		SearchCriteria assetCriteria = getAssetCriteria();
		Entity asset = assetCriteria.getParameter("asset", Entity.class);

		criteria.addParameter(test);
		criteria.addParameter(asset);

		Association a = new Association("titleAssetAssociation", test,
				"asset.id", asset, "id");
		criteria.addParameter(a);

		criteria.setRecordsCount(Integer.MAX_VALUE);

		return criteria;
	}

	private SearchCriteria getSearchCriteria2() {
		SearchCriteria criteria = new SearchCriteria();

		Entity test = new Entity("testTitle", Title.class, "testtitle");
		// test.addParameter(new SortParameter("id", SortingOrder.ASCENDING));

		test.addParameter(new ValueParameter("asset.root", SearchType.STRING,
				(Object) null));

		// search info
		Entity assetField = new Entity("field",
				"asset.allDescendantAssetFields", "f");
		assetField.addParameter(new ValueParameter("ttvXPath",
				SearchType.STRING, "f1", SearchOperator.EQUAL));
		assetField.addParameter(new ValueParameter("value", SearchType.STRING,
				"value2", SearchOperator.EQUAL));
		test.addParameter(assetField);

		// sort info
		Entity field = new Entity("field", "allDescendantAssetFields", "f");
		field.setJoin(Join.LEFT_OUTER);
		field.setFetch(true);
		field.addParameter(new SortParameter("value", SortingOrder.ASCENDING));
		field.addParameter(new ValueParameter("ttvXPath", SearchType.STRING,
				"f2", SearchOperator.EQUAL));
		assetField.addParameter(field);

		criteria.addParameter(test);

		criteria.setRecordsCount(Integer.MAX_VALUE);

		return criteria;
	}

	private SearchCriteria getAssetCriteria() {
		SearchCriteria criteria = new SearchCriteria();

		Entity asset = new Entity("asset", Asset.class, "testasset");
		asset.addParameter(new ValueParameter("root", SearchType.STRING,
				(Object) null));

		// search info
		Entity assetField = new Entity("field", "allDescendantAssetFields", "f");
		assetField.addParameter(new ValueParameter("ttvXPath",
				SearchType.STRING, "f1", SearchOperator.EQUAL));
		assetField.addParameter(new ValueParameter("value", SearchType.STRING,
				"value2", SearchOperator.EQUAL));
		asset.addParameter(assetField);

		// sort info
		Entity field = new Entity("field", "allDescendantAssetFields", "f");
		field.setJoin(Join.LEFT_OUTER);
		field.setFetch(true);
		field.addParameter(new SortParameter("value", SortingOrder.ASCENDING));
		field.addParameter(new ValueParameter("ttvXPath", SearchType.STRING,
				"f2", SearchOperator.EQUAL));
		asset.addParameter(field);

		criteria.addParameter(asset);

		return criteria;
	}
}
