package com.hammurapi.extract;

import java.util.Map;
import java.util.Set;

/**
 * Utility class.
 * @author Pavel Vlasov
 *
 */
public class ExtractorUtil {
	
	private ExtractorUtil() {
		// TODO Auto-generated constructor stub
	}
	
	/**
	 * Wraps extractor into predicate, if given extractor is not already a predicate.
	 * @param <T>
	 * @param <C>
	 * @param extractor
	 * @return
	 */
	public static <T,C> Predicate<T,C> wrap(final Extractor<T,Boolean,C> extractor) {
		if (extractor instanceof Predicate) {
			return (Predicate<T,C>) extractor;
		}
		
		return new Predicate<T,C>() {

			@Override
			public Boolean extract(
					C context,
					Map<C, Map<Extractor<T, ? super Boolean, C>, ? super Boolean>> cache,
					T... obj) {
				return extractor.extract(context, cache, obj);
			}

			@Override
			public Set<Integer> parameterIndices() {
				return extractor.parameterIndices();
			}

			@Override
			public boolean isContextDependent() {
				return extractor.isContextDependent();
			}

			@Override
			public ComparisonResult compareTo(Extractor<T, Boolean, C> other) {
				return extractor.compareTo(other);
			}
			
			@Override
			public double getCost() {
				return extractor.getCost();
			}
			
		};
		
	}
	
	/**
	 * 
	 * @param <T>
	 * @param <V>
	 * @param <C>
	 * @param source Source extractor.
	 * @return Instance of mappable if extractor is mappable or its parameter indices is empty. Null otherwise.
	 */
	public static <T,V,C> Mappable<T,V,C> toMappable(final Extractor<T,V,C> source) {
		if (source==null) {
			return null;
		}
		if (source instanceof Mappable) {
			return (Mappable<T,V,C>) source;
		}
		if (source.parameterIndices().isEmpty()) {
			return new Mappable<T,V,C>() {

				@Override
				public Extractor<T, V, C> map(int[] map) {
					return source;
				}
				
			};
		}
		return null;
	}

}
