package com.tandbergtv.metadata.test.search;

import static org.springframework.transaction.TransactionDefinition.PROPAGATION_REQUIRED;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import junit.framework.TestCase;

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 com.tandbergtv.metadatamanager.model.Asset;
import com.tandbergtv.metadatamanager.model.Field;
import com.tandbergtv.metadatamanager.model.ParentChildRelation;
import com.tandbergtv.metadatamanager.model.Relation;
import com.tandbergtv.metadatamanager.search.AssetSearchService;
import com.tandbergtv.metadatamanager.search.ListFieldInfo;
import com.tandbergtv.metadatamanager.search.LogicalOperator;
import com.tandbergtv.metadatamanager.search.MetadataValueFieldInfo;
import com.tandbergtv.metadatamanager.search.RangeFieldInfo;
import com.tandbergtv.metadatamanager.search.SearchField;
import com.tandbergtv.metadatamanager.search.SearchInfo;
import com.tandbergtv.metadatamanager.search.SortInfo;
import com.tandbergtv.watchpoint.search.Entity;
import com.tandbergtv.watchpoint.search.NestedQueryEntity;
import com.tandbergtv.workflow.driver.search.SearchOperator;
import com.tandbergtv.workflow.driver.search.SearchType;
import com.tandbergtv.workflow.driver.search.ValueParameter;
import com.tandbergtv.workflow.util.SearchCriteria;
import com.tandbergtv.workflow.util.SortingOrder;

public class AssetSearchCriteriaTest extends TestCase {

	private ApplicationContext context;
	private AssetSearchService searchService;

	/*
	 * (non-Javadoc)
	 * 
	 * @see junit.framework.TestCase#setUp()
	 */
	@Override
	protected void setUp() throws Exception {
		super.setUp();

		this.context = new ClassPathXmlApplicationContext(new String[] {
				"MetadataBeansContext.xml",
				"MetadataManagerDBContext.xml",
				"file:tests/DataSource_UnitTest.xml" });
		this.searchService = (AssetSearchService) context
				.getBean("assetSearch");
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see junit.framework.TestCase#tearDown()
	 */
	@Override
	protected void tearDown() throws Exception {
		super.tearDown();
	}

	public void _testValueFieldInfoCriteria() {
		//MetadataValueFieldInfo vinfo = new MetadataValueFieldInfo("/tns:Fields/tns:Content/tns:Locator/tns:Uri", SearchOperator.EQUAL, "Mandolin.mpg");
		
		
		MetadataValueFieldInfo vinfo = new MetadataValueFieldInfo("/tns:Fields/tns:CustomFields/tns:CustomField[@name=ABCD]/@value", LogicalOperator.EQUAL, "11");
//		MetadataValueFieldInfo xinfo = new MetadataValueFieldInfo("/tns:Fields/tns:Version/tns:Major", SearchOperator.GREATERTHANEQUAL, "22", true);
//		MetadataValueFieldInfo yinfo = new MetadataValueFieldInfo("/tns:Fields/tns:Version/tns:Minor", SearchOperator.GREATERTHANEQUAL, "0", false);
//		MetadataValueFieldInfo vinfo = new MetadataValueFieldInfo("/tns:Fields/tns:Content", SearchOperator.ISEMPTY, "", true);
//		vinfo.setAssetType("PACKAGE");
		SearchInfo searchInfo = new SearchInfo();
//		searchInfo.getFields().add(xinfo);
//		searchInfo.getFields().add(yinfo);
		List<SearchField> fields = new ArrayList<SearchField>();
		fields.add(vinfo);
		searchInfo.setFields(fields);
		searchInfo.setProperty("allDescendantAssetFields");

		SortInfo sortInfo = new SortInfo();
		sortInfo.setOrder(SortingOrder.ASCENDING);
		sortInfo.setProperty("allDescendantAssetFields");
		sortInfo.setSortItemName("/tns:Fields/tns:AssetName");

		// not supported any more!!
//		SearchCriteria criteria = searchService.getCriteria("rootAsset", searchInfo, null, 0);
//		search(criteria);
	}

	public void _testRangeFieldInfoCriteria() {
		RangeFieldInfo rinfo = new RangeFieldInfo("/tns:Fields/tns:ProviderInfo/tns:Identifier/tns:Id", "12344", "12346");
		//RangeFieldInfo rinfo = new RangeFieldInfo("/tns:Fields/tns:CreationInfo/tns:CreateDate", "2002-03-04", "2002-03-05", true);
		//RangeFieldInfo rinfo = new RangeFieldInfo("/tns:Fields/tns:CustomFields/tns:CustomField[@name=ABCD]/@value", "10", "12");
		SearchInfo searchInfo = new SearchInfo();
		List<SearchField> fields = new ArrayList<SearchField>();
		fields.add(rinfo);
		searchInfo.setFields(fields);
		searchInfo.setProperty("allDescendantAssetFields");

		SortInfo sortInfo = new SortInfo();
		sortInfo.setOrder(SortingOrder.ASCENDING);
		sortInfo.setProperty("allDescendantAssetFields");
		sortInfo.setSortItemName("/tns:Fields/tns:AssetName");

		// not supported any more!!
//		SearchCriteria criteria = searchService.getCriteria("rootAsset", searchInfo, null, 0);
//		search(criteria);
	}

	public void testListFieldInfoCriteria() {
		List<String> values = new ArrayList<String>();
		values.add("8888");
		values.add("11221");
		values.add("1222");
		
		ListFieldInfo linfo = new ListFieldInfo("/tns:Fields/tns:CustomFields/tns:CustomField[@name=ABCD]/@value", values, LogicalOperator.IN, true);
//		linfo.setAssetType("MOVIE");
		SearchInfo searchInfo = new SearchInfo();
		List<SearchField> fields = new ArrayList<SearchField>();
		fields.add(linfo);
		searchInfo.setFields(fields);
		searchInfo.setProperty("allDescendantAssetFields");

		SortInfo sortInfo = new SortInfo();
		sortInfo.setOrder(SortingOrder.ASCENDING);
		sortInfo.setProperty("allDescendantAssetFields");
		sortInfo.setSortItemName("/tns:Fields/tns:AssetName");

		// not supported any more!!
//		SearchCriteria criteria = searchService.getCriteria("rootAsset", searchInfo, null, 0);
//		search(criteria);
	}

	/**
	 * @param criteria
	 */
	private void search(SearchCriteria criteria) {
		PlatformTransactionManager txmgr = (PlatformTransactionManager) context
				.getBean("transactionManager");
		TransactionStatus status = txmgr
				.getTransaction(new DefaultTransactionDefinition(
						PROPAGATION_REQUIRED));

		// not supported any more!!
		// Collection<Asset> assets = searchService.search(criteria);

		Collection<Asset> assets = new ArrayList<Asset>();
		for (Asset asset : assets) {
			printAsset(asset);
		}

		// not supported any more!!
		// System.out.println("Count " + searchService.count(criteria));

		txmgr.commit(status);
	}

	void printAsset(Asset asset) {
		int children = 0;

		for (Relation relation : asset.getRelations()) {
			if (relation instanceof ParentChildRelation
					&& asset.equals(relation.getOwnerAsset())) {
				children++;
			}
		}

		System.out.println(asset.getId() + ", " + children + " kid(s)");

		for (Field field : asset.getFields()) {
			System.out.println("\t" + field.getTtvXPath() + ", "
					+ field.getValue());
		}
	}
	
	
	public void _testNestedQuery() {
		Entity assetEntity = new Entity("rootAsset", Asset.class, "a");
		Entity field = new Entity("field", "allDescendantAssetFields", "f");
		field.addParameter(new ValueParameter("ttvXPath",
				SearchType.STRING, "/tns:Fields/tns:Content", SearchOperator.ISEMPTY));
		assetEntity.addParameter(field);
		
		NestedQueryEntity n = new NestedQueryEntity("rootAsset", Asset.class, "na");
		n.setOperator(SearchOperator.NOTIN);
		
		n.addParameter(assetEntity);
		
		
		com.tandbergtv.workflow.util.SearchCriteria crit = new com.tandbergtv.workflow.util.SearchCriteria();
		crit.addParameter(n);
		
		search(crit);
	}
}
