// Path: fhir-index-plugin/src/main/java/io/puntanegra/fhir/index/search/datatypes/AbstractSearchParam.java
// public abstract class AbstractSearchParam {
// 
// 	static final int MAX_SP_NAME = 200;
// 
// 	protected String name;
// 	protected String path;
// 	protected SearchParamTypes type;
// 
// 	public AbstractSearchParam() {
// 
// 	}
// 
// 	public AbstractSearchParam(String name, String path, SearchParamTypes type) {
// 		super();
// 		this.name = name;
// 		this.path = path;
// 		this.type = type;
// 	}
// 
// 	public String getName() {
// 		return name;
// 	}
// 
// 	public String getPath() {
// 		return path;
// 	}
// 
// 	public SearchParamTypes getType() {
// 		return type;
// 	}
// 
// 	public String getTypeAsString() {
// 		return type.name();
// 	}
// 
// 	public void setTypeAsString(String type) {
// 		this.type = SearchParamTypes.valueOf(type);
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "ResourceSearchParameters [name=" + name + ", path=" + path + ", type=" + type + "]";
// 	}
// 
// 	// TODO: finish this code
// 	public String getTypeAsCassandraDataType() {
// 		if (this.type == SearchParamTypes.NUMBER) {
// 			return "double";
// 		} else if (this.type == SearchParamTypes.QUANTITY) {
// 			return "double";
// 		} else if (this.type == SearchParamTypes.DATE) {
// 			return "timestamp";
// 		} else {
// 			return "text";
// 		}
// 	}
// 
// 	public abstract boolean hasValue();
// 
// 	public abstract String getValueAsString();
// 
// 	public abstract Object getValue();
// 
// 	public abstract List<Field> createIndexedFields();
// 
// 	public List<Field> createSortedFields() {
// 		return Collections.emptyList();
// 	};
// }
// 
// Path: fhir-index-plugin/src/main/java/io/puntanegra/fhir/index/search/datatypes/SearchParamDates.java
// public class SearchParamDates extends AbstractSearchParam {
// 	private Date low;
// 	private Date high;
// 
// 	private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
// 
// 	public SearchParamDates(String name, String path, SearchParamTypes type, Date low, Date high) {
// 		super(name, path, type);
// 		this.low = low;
// 		this.high = high;
// 	}
// 
// 	@Override
// 	public boolean hasValue() {
// 		return low != null;
// 	}
// 
// 	@Override
// 	public String getValueAsString() {
// 		// TODO Auto-generated method stub
// 		return null;
// 	}
// 
// 	public Date getLow() {
// 		return low;
// 	}
// 
// 	public void setLow(Date low) {
// 		this.low = low;
// 	}
// 
// 	public Date getHigh() {
// 		return high;
// 	}
// 
// 	public void setHigh(Date high) {
// 		this.high = high;
// 	}
// 
// 	@Override
// 	public Date getValue() {
// 		return this.low;
// 	}
// 
// 	@Override
// 	public List<Field> createIndexedFields() {
// 		Field fieldLow = new StringField(name, dateFormat.format(this.low), Field.Store.NO);
// 
// 		// TODO: ver como se busca por un periodo
// 		Field fieldHigh = null;
// 		if (this.high != null) {
// 			fieldHigh = new StringField(name + "_high", dateFormat.format(this.high), Field.Store.NO);
// 		}
// 
// 		if (fieldHigh == null) {
// 			return Arrays.asList(fieldLow);
// 		} else {
// 			return Arrays.asList(fieldLow, fieldHigh);
// 		}
// 	}
// 
// }
// 
// Path: fhir-index-plugin/src/main/java/io/puntanegra/fhir/index/search/datatypes/SearchParamTypes.java
// public enum SearchParamTypes {
// 	NUMBER, DATE, STRING, TOKEN, REFERENCE, COMPOSITE, QUANTITY, URI;
// }


import java.util.HashSet;
import java.util.Set;
import org.hl7.fhir.dstu3.model.BaseDateTimeType;
import org.hl7.fhir.dstu3.model.Period;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeSearchParam;
import io.puntanegra.fhir.index.search.datatypes.AbstractSearchParam;
import io.puntanegra.fhir.index.search.datatypes.SearchParamDates;
import io.puntanegra.fhir.index.search.datatypes.SearchParamTypes;
package io.puntanegra.fhir.index.search.extractor;




/**
 * Extracts information from dates attribute types.
 * 
 * @author Jorge L. Middleton {@literal <jorge.middleton@gmail.com>}
 *
 */
public class DatesSearchParameterExtractor extends AbstractSearchParameterExtractor {

	public DatesSearchParameterExtractor(FhirContext ctx) {
		super(ctx);
	}

	@Override
	public Set<AbstractSearchParam> extractValues(IBaseResource instance, RuntimeSearchParam searchParam) {

		Set<AbstractSearchParam> values = new HashSet<AbstractSearchParam>();

		String path = searchParam.getPath();
		String resourceName = searchParam.getName();
		String paramType = getParamType(searchParam);

		for (Object obj : extractValues(path, instance)) {
			if (obj == null || ((IBase) obj).isEmpty()) {
				continue;
			}

// Path: fhir-index-plugin/src/main/java/io/puntanegra/fhir/index/search/datatypes/AbstractSearchParam.java
// public abstract class AbstractSearchParam {
// 
// 	static final int MAX_SP_NAME = 200;
// 
// 	protected String name;
// 	protected String path;
// 	protected SearchParamTypes type;
// 
// 	public AbstractSearchParam() {
// 
// 	}
// 
// 	public AbstractSearchParam(String name, String path, SearchParamTypes type) {
// 		super();
// 		this.name = name;
// 		this.path = path;
// 		this.type = type;
// 	}
// 
// 	public String getName() {
// 		return name;
// 	}
// 
// 	public String getPath() {
// 		return path;
// 	}
// 
// 	public SearchParamTypes getType() {
// 		return type;
// 	}
// 
// 	public String getTypeAsString() {
// 		return type.name();
// 	}
// 
// 	public void setTypeAsString(String type) {
// 		this.type = SearchParamTypes.valueOf(type);
// 	}
// 
// 	@Override
// 	public String toString() {
// 		return "ResourceSearchParameters [name=" + name + ", path=" + path + ", type=" + type + "]";
// 	}
// 
// 	// TODO: finish this code
// 	public String getTypeAsCassandraDataType() {
// 		if (this.type == SearchParamTypes.NUMBER) {
// 			return "double";
// 		} else if (this.type == SearchParamTypes.QUANTITY) {
// 			return "double";
// 		} else if (this.type == SearchParamTypes.DATE) {
// 			return "timestamp";
// 		} else {
// 			return "text";
// 		}
// 	}
// 
// 	public abstract boolean hasValue();
// 
// 	public abstract String getValueAsString();
// 
// 	public abstract Object getValue();
// 
// 	public abstract List<Field> createIndexedFields();
// 
// 	public List<Field> createSortedFields() {
// 		return Collections.emptyList();
// 	};
// }
// 
// Path: fhir-index-plugin/src/main/java/io/puntanegra/fhir/index/search/datatypes/SearchParamDates.java
// public class SearchParamDates extends AbstractSearchParam {
// 	private Date low;
// 	private Date high;
// 
// 	private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
// 
// 	public SearchParamDates(String name, String path, SearchParamTypes type, Date low, Date high) {
// 		super(name, path, type);
// 		this.low = low;
// 		this.high = high;
// 	}
// 
// 	@Override
// 	public boolean hasValue() {
// 		return low != null;
// 	}
// 
// 	@Override
// 	public String getValueAsString() {
// 		// TODO Auto-generated method stub
// 		return null;
// 	}
// 
// 	public Date getLow() {
// 		return low;
// 	}
// 
// 	public void setLow(Date low) {
// 		this.low = low;
// 	}
// 
// 	public Date getHigh() {
// 		return high;
// 	}
// 
// 	public void setHigh(Date high) {
// 		this.high = high;
// 	}
// 
// 	@Override
// 	public Date getValue() {
// 		return this.low;
// 	}
// 
// 	@Override
// 	public List<Field> createIndexedFields() {
// 		Field fieldLow = new StringField(name, dateFormat.format(this.low), Field.Store.NO);
// 
// 		// TODO: ver como se busca por un periodo
// 		Field fieldHigh = null;
// 		if (this.high != null) {
// 			fieldHigh = new StringField(name + "_high", dateFormat.format(this.high), Field.Store.NO);
// 		}
// 
// 		if (fieldHigh == null) {
// 			return Arrays.asList(fieldLow);
// 		} else {
// 			return Arrays.asList(fieldLow, fieldHigh);
// 		}
// 	}
// 
// }
// 
// Path: fhir-index-plugin/src/main/java/io/puntanegra/fhir/index/search/datatypes/SearchParamTypes.java
// public enum SearchParamTypes {
// 	NUMBER, DATE, STRING, TOKEN, REFERENCE, COMPOSITE, QUANTITY, URI;
// }


// Path: fhir-index-plugin/src/main/java/io/puntanegra/fhir/index/search/extractor/DatesSearchParameterExtractor.java
import java.util.HashSet;
import java.util.Set;
import org.hl7.fhir.dstu3.model.BaseDateTimeType;
import org.hl7.fhir.dstu3.model.Period;
import org.hl7.fhir.instance.model.api.IBase;
import org.hl7.fhir.instance.model.api.IBaseResource;
import ca.uhn.fhir.context.FhirContext;
import ca.uhn.fhir.context.RuntimeSearchParam;
import io.puntanegra.fhir.index.search.datatypes.AbstractSearchParam;
import io.puntanegra.fhir.index.search.datatypes.SearchParamDates;
import io.puntanegra.fhir.index.search.datatypes.SearchParamTypes;

package io.puntanegra.fhir.index.search.extractor;




/**
 * Extracts information from dates attribute types.
 * 
 * @author Jorge L. Middleton {@literal <jorge.middleton@gmail.com>}
 *
 */
public class DatesSearchParameterExtractor extends AbstractSearchParameterExtractor {

	public DatesSearchParameterExtractor(FhirContext ctx) {
		super(ctx);
	}

	@Override
	public Set<AbstractSearchParam> extractValues(IBaseResource instance, RuntimeSearchParam searchParam) {

		Set<AbstractSearchParam> values = new HashSet<AbstractSearchParam>();

		String path = searchParam.getPath();
		String resourceName = searchParam.getName();
		String paramType = getParamType(searchParam);

		for (Object obj : extractValues(path, instance)) {
			if (obj == null || ((IBase) obj).isEmpty()) {
				continue;
			}

			boolean multiType = false;