package industries.doublehelix.conditionalfilter.filtertypes.flat;

import java.util.Arrays;
import java.util.TreeSet;

/**
 * A filter for a string type with only fixed values possible
 * note that this filter is ALWAYS case sensitive in it's toString() or sql statement functions
 * @author klaue
 *
 */
public class FixedValuesStringFilter extends StringFilter {
	private static final long serialVersionUID = 1L;
	TreeSet<String> possibleValues = null;
	
	/**
	 * A filter for a string field with fixed values
	 * Is always case sensitive
	 * @param filterMode either IS or ISNOT, there is no try err contains for fixed values filter
	 * @param filterName the name of the filtered attribute 
	 * @param filterRawName the name of the filter for the generated SQL (null for same as filterName)
	 * @param possibleValues the values possible to be set
	 */
	public FixedValuesStringFilter(StringFilterMode filterMode, String filterName, String filterRawName, TreeSet<String> possibleValues) {
		super(filterMode, filterName, filterRawName);
		this.possibleValues = possibleValues;
	}
	
	/**
	 * A filter for a string field with fixed values
	 * Is always case sensitive
	 * @param filterMode either IS or ISNOT, there is no try err contains for fixed values filter
	 * @param filterName the name of the filtered attribute 
	 * @param filterRawName the name of the filter for the generated SQL (null for same as filterName)
	 * @param possibleValues the values possible to be set
	 */
	public FixedValuesStringFilter(StringFilterMode filterMode, String filterName, String filterRawName, String... possibleValues) {
		super(filterMode, filterName, filterRawName);
		this.possibleValues = new TreeSet<>(Arrays.asList(possibleValues));
	}
	
	/**
	 * A filter template for a string field with fixed values
	 * @param filterName the name of the filtered attribute 
	 * @param filterRawName the name of the filter for the generated SQL (null for same as filterName)
	 * @param possibleValues the values possible to be set
	 */
	public FixedValuesStringFilter(String filterName, String filterRawName, TreeSet<String> possibleValues) {
		super(filterName, filterRawName);
		this.possibleValues = possibleValues;
	}
	
	/**
	 * A filter template for a string field with fixed values
	 * @param filterName the name of the filtered attribute 
	 * @param filterRawName the name of the filter for the generated SQL (null for same as filterName)
	 * @param possibleValues the values possible to be set
	 */
	public FixedValuesStringFilter(String filterName, String filterRawName, String... possibleValues) {
		super(filterName, filterRawName);
		this.possibleValues = new TreeSet<>(Arrays.asList(possibleValues));
	}
	
	@Override
	public void setFilterMode(StringFilterMode filterMode) {
		if (filterMode != null && filterMode != StringFilterMode.IS && filterMode != StringFilterMode.ISNOT) {
			throw new IllegalArgumentException("FilterMode " + filterMode.name() + " is not valid for FixedValuesStringFilter");
		}
		super.setFilterMode(filterMode);
	}

	/**
	 * sets a new filter string. if the string is not in the possibleValues set for this filter (case sensitive),
	 * filter string of this filter is not changed
	 */
	public void setString(String filterString) {
		if (possibleValues.contains(filterString)) {
			super.setString(filterString);
		} else {
			throw new IllegalArgumentException("String " + filterString + " is not valid for this FixedValuesStringFilter");
		}
	}
	
	@Override
	protected String prepareFilterStringForSQL() {
		return this.filterString; // unchanged
	}
	
	@Override
	protected String prepareFieldForSQL(String field) {
		return field; // unchanged
	}

	/**
	 * @return the possible values for this filter
	 */
	public TreeSet<String> getPossibleValues() {
		return possibleValues;
	}

	/**
	 * set the possible values for this filter. Values are case sensitive
	 * @param possibleValues
	 */
	public void setPossibleValues(TreeSet<String> possibleValues) {
		this.possibleValues = possibleValues;
	}
	
}
