package org.gcube.portlets.user.speciesdiscovery.server.util;

import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.RecognitionException;
import org.apache.log4j.Logger;
import org.gcube.dataaccess.spql.SPQLLexer;
import org.gcube.dataaccess.spql.SPQLParser;
import org.gcube.dataaccess.spql.model.ParsingResult;
import org.gcube.dataaccess.spql.model.ReturnType;
import org.gcube.portlets.user.speciesdiscovery.shared.SearchFilters;
import org.gcube.portlets.user.speciesdiscovery.shared.SearchResultType;
import org.gcube.portlets.user.speciesdiscovery.shared.SearchServiceException;
import org.gcube.portlets.user.speciesdiscovery.shared.SpeciesCapability;

/**
 * @author "Federico De Faveri defaveri@isti.cnr.it"
 *
 */
public class QueryUtil {

	protected static Logger logger = Logger.getLogger(QueryUtil.class);

	public static SearchResultType getQueryResultType(String query) throws SearchServiceException
	{
		try {
			SPQLLexer lexer = new SPQLLexer(new ANTLRStringStream(query));
			CommonTokenStream tokens = new CommonTokenStream(lexer);
			SPQLParser parser = new SPQLParser(tokens);
			ParsingResult result = parser.query();

			ReturnType type = result.getReturnExpression().getType();
			if (type == null) return SearchResultType.SPECIES_PRODUCT;
			switch (type) {
				case ALL: return SearchResultType.SPECIES_PRODUCT;
				case OCCURRENCE: return SearchResultType.OCCURRENCE_POINT;
				case TAXON: return SearchResultType.TAXONOMY_ITEM;
				default: logger.error("Unknow return type: "+type);
			}

		} catch (RecognitionException e) {
			logger.warn("Error parsing the user query", e);
			throw new SearchServiceException("Wrong query: "+e.getMessage());
		}


		return null;
	}
	
	public static SearchResultType getResultType(SearchFilters searchFilters)
	{
		
		switch (searchFilters.getResultType()) {
			case RESULTITEM: return SearchResultType.SPECIES_PRODUCT;
			case TAXONOMYITEM: return SearchResultType.TAXONOMY_ITEM;
			default: logger.error("Unknow return type: "+searchFilters.getResultType());
		}
		return null;
	}
	
	public static SpeciesCapability getResultType(SearchResultType resultType)
	{
		
		switch (resultType) {
			case SPECIES_PRODUCT: return SpeciesCapability.RESULTITEM;
			case OCCURRENCE_POINT: return SpeciesCapability.OCCURRENCESPOINTS;
			case TAXONOMY_ITEM: return SpeciesCapability.TAXONOMYITEM;
		}
		return null;
	}
}
