package com.tandbergtv.metadatamanager.search;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

import com.tandbergtv.metadatamanager.model.Asset;
import com.tandbergtv.metadatamanager.model.AssetState;
import com.tandbergtv.watchpoint.search.Entity;
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;

/**
 * Helper class to get the search criteria from the given list of search fields
 * 
 * @author spuranik
 * 
 */
public class CriteriaBuilder {

	protected static final String IFIELD_COLLECTION_NAME_FIELDS = "fields";
	protected static final String IFIELD_ENTITY_NAME_FIELD = "field";
	
	protected static final String IFIELD_COLLECTION_NAME_FIELD_REVISIONS = "fieldRevisions";
	protected static final String IFIELD_ENTITY_NAME_FIELD_REVISION = "fieldRevision";

	public static SearchCriteria baseBuildIFieldSearchCriteria(
			com.tandbergtv.metadatamanager.model.SearchCriteria criteria, String iFieldEntityName, String iFieldCollectionName, boolean idOnly) {
		// if no criteria was specified, return an empty list
		// TODO: how do we search for all assets (a search with no filter and
		// result needed is all assets)
		if (criteria.entrySet().size() == 0) {
			return new com.tandbergtv.workflow.util.SearchCriteria();
		}

		com.tandbergtv.workflow.util.SearchCriteria crit = new com.tandbergtv.workflow.util.SearchCriteria();
		Entity assetEntity = new Entity("asset", Asset.class, "a");

		if(idOnly) {
			List<String> selectPropertyNames = new ArrayList<String>();
			selectPropertyNames.add("id");
			assetEntity.setSelectPropertyNames(selectPropertyNames);
		}
		
		Iterator<Entry<String, String>> entryIterator = criteria.entrySet()
				.iterator();
		while (entryIterator.hasNext()) {
			Entry<String, String> entry = entryIterator.next();
			String xpath = entry.getKey();
			String value = entry.getValue();
			if (xpath.equals("rootlevel")) {
				assetEntity.addParameter(new ValueParameter(
						AssetSearchKey.ASSET_ROOT.toString(),
						SearchType.NUMERIC, (Object) null));
			} else {
				Entity field = new Entity(iFieldEntityName, iFieldCollectionName, "f");
				field.addParameter(new ValueParameter(AssetSearchKey.TTV_XPATH
						.toString(), SearchType.STRING, xpath,
						SearchOperator.EQUAL));
				SearchType st = SearchDataTypeHelper.getSearchType(xpath);
				field.addParameter(new ValueParameter(
						AssetSearchKey.FIELD_VALUE.toString(), st, value));
				assetEntity.addParameter(field);
			}
		}

		assetEntity.addParameter(new ValueParameter(AssetSearchKey.ASSET_STATE
				.toString(), SearchType.NUMERIC, AssetState.ACTIVE.ordinal()));

		crit.addParameter(assetEntity);
		crit.setRecordsCount(Integer.MAX_VALUE);

		return crit;
	}

	public static SearchCriteria buildSearchCriteria(
			com.tandbergtv.metadatamanager.model.SearchCriteria criteria, boolean idOnly) {

		com.tandbergtv.workflow.util.SearchCriteria crit = new com.tandbergtv.workflow.util.SearchCriteria();
		Entity assetEntity = new Entity("asset", Asset.class, "a");

		if(idOnly) {
			List<String> selectPropertyNames = new ArrayList<String>();
			selectPropertyNames.add("id");
			assetEntity.setSelectPropertyNames(selectPropertyNames);
		}
		
		Iterator<Entry<String, String>> iter = criteria.entrySet().iterator();
		while (iter.hasNext()) {
			Entry<String, String> entry = iter.next();
			SearchType st = SearchDataTypeHelper.getAssetSearchType(entry
					.getKey());
			assetEntity.addParameter(new ValueParameter(entry.getKey(), st,
					entry.getValue(), SearchOperator.EQUAL));
		}

		assetEntity.addParameter(new ValueParameter(AssetSearchKey.ASSET_STATE
				.toString(), SearchType.NUMERIC, AssetState.ACTIVE.ordinal()));

		crit.addParameter(assetEntity);
		crit.setRecordsCount(Integer.MAX_VALUE);

		return crit;
	}

	/**
	 * build search based on Fields
	 * @param criteria
	 * @return
	 */
	public static SearchCriteria buildFieldSearchCriteria(com.tandbergtv.metadatamanager.model.SearchCriteria criteria, boolean idOnly) {
		return baseBuildIFieldSearchCriteria(criteria, IFIELD_ENTITY_NAME_FIELD, IFIELD_COLLECTION_NAME_FIELDS, idOnly);
	}

	/**
	 * build search based on FieldRevisions
	 * @param criteria
	 * @return
	 */
	public static SearchCriteria buildFieldRevisionSearchCriteria(
			com.tandbergtv.metadatamanager.model.SearchCriteria criteria, boolean idOnly) {
		return baseBuildIFieldSearchCriteria(criteria, IFIELD_ENTITY_NAME_FIELD_REVISION,
				IFIELD_COLLECTION_NAME_FIELD_REVISIONS, idOnly);
	}
	
	
}
