package eu.dnetlib.functionality.cql;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import eu.dnetlib.functionality.cql.lucene.TranslatedQuery;
import org.bson.conversions.Bson;
import org.z3950.zing.cql.CQLNode;
import org.z3950.zing.cql.CQLParseException;

import com.google.common.collect.BiMap;

public interface CqlTranslator {

	/**
	 * main translator method
	 * 
	 * @param queryRoot
	 *            String representation of the cql query
	 * @param options
	 *            options that modify the behavior of cql parsing
	 * @return String representing the query in the lucene syntax
	 * @throws CQLParseException
	 * @throws IOException
	 */
	public String toLucene(final String queryRoot) throws CQLParseException, IOException;

	/**
	 * main translator method
	 * 
	 * @param queryRoot
	 *            String representation of the cql query
	 * @return String representing the query in the lucene syntax
	 * @throws CQLParseException
	 * @throws IOException
	 */
	public String toLucene(final String queryRoot, Map<String, List<String>> options) throws CQLParseException, IOException;

	/**
	 * main translator method
	 * 
	 * @param queryRoot
	 *            String representation of the cql query
	 * @param valueTransformerMap
	 *            callbacks which allow us to normalize field values when we know about them
	 * @return String representing the query in the lucene syntax
	 * @throws CQLParseException
	 * @throws IOException
	 */
	public String toLucene(final String queryRoot, CqlValueTransformerMap valueTransformerMap) throws CQLParseException, IOException;

	/**
	 * main translator method
	 * 
	 * @param queryRoot
	 *            Pre-parsed representation of the cql query
	 * @return String representing the query in the lucene syntax
	 * @throws CQLParseException
	 * @throws IOException
	 */
	public String toLucene(final CQLNode queryRoot) throws CQLParseException, IOException;

	/**
	 * main translator method
	 * 
	 * @param queryRoot
	 *            Pre-parsed representation of the cql query
	 * @param valueTransformerMap
	 *            callbacks which allow us to normalize field values when we know about them
	 * @return String representing the query in the lucene syntax
	 * @throws CQLParseException
	 * @throws IOException
	 */
	public String toLucene(final CQLNode queryRoot, CqlValueTransformerMap valueTransformerMap) throws CQLParseException, IOException;

	/**
	 * main translator method
	 * 
	 * @param queryRoot
	 *            Pre-parsed representation of the cql query
	 * @param valueTransformerMap
	 *            callbacks which allow us to normalize field values when we know about them
	 * @param options
	 *            options that modify the behavior of cql parsing
	 * @return String representing the query in the lucene syntax
	 * @throws CQLParseException
	 * @throws IOException
	 */
	public String toLucene(final CQLNode queryRoot, CqlValueTransformerMap valueTransformerMap, Map<String, List<String>> options)
			throws CQLParseException, IOException;

	/**
	 * method performs the translation and returns a TranslatedQuery object which contains the translated query and the
	 * cql-related options.
	 * 
	 * @param queryRoot
	 *            Pre-parsed representation of the cql query
	 * @param valueTransformerMap
	 *            callbacks which allow us to normalize field values when we know about them
	 * @return TranslatedQuery object which contains the translated query and the cql-related options
	 * @throws CQLParseException
	 * @throws IOException
	 */
	public TranslatedQuery getTranslatedQuery(final String cqlQuery) throws CQLParseException, IOException;

	/**
	 * method performs the translation and returns a TranslatedQuery object which contains the translated query and the
	 * cql-related options.
	 * 
	 * @param queryRoot
	 *            Pre-parsed representation of the cql query
	 * @param valueTransformerMap
	 *            callbacks which allow us to normalize field values when we know about them
	 * @return TranslatedQuery object which contains the translated query and the cql-related options
	 * @throws CQLParseException
	 * @throws IOException
	 */
	public TranslatedQuery getTranslatedQuery(final CQLNode queryRoot, CqlValueTransformerMap valueTransformerMap) throws CQLParseException, IOException;

	/**
	 * method performs the translation and returns a TranslatedQuery object which contains the translated query and the
	 * cql-related options.
	 * 
	 * @param queryRoot
	 *            Pre-parsed representation of the cql query
	 * @param valueTransformerMap
	 *            callbacks which allow us to normalize field values when we know about them
	 * @param options
	 *            options that modify the behavior of cql parsing
	 * @return TranslatedQuery object which contains the translated query and the cql-related options
	 * @throws CQLParseException
	 * @throws IOException
	 */
	public TranslatedQuery getTranslatedQuery(
			final CQLNode queryRoot,
			CqlValueTransformerMap valueTransformerMap,
			Map<String, List<String>> options,
			BiMap<String, String> aliases,
			Map<String, String> weights) throws CQLParseException, IOException;

	/**
	 * method performs the translation and returns a TranslatedQuery object which contains the translated query and the
	 * cql-related options.
	 * 
	 * @param queryRoot
	 *            Pre-parsed representation of the cql query
	 * @param valueTransformerMap
	 *            callbacks which allow us to normalize field values when we know about them
	 * @param options
	 *            options that modify the behavior of cql parsing
	 * @return TranslatedQuery object which contains the translated query and the cql-related options
	 * @throws CQLParseException
	 * @throws IOException
	 */
	public TranslatedQuery getTranslatedQuery(final String cqlQuery, Map<String, List<String>> options) throws CQLParseException, IOException;

	/**
	 * method performs the translation and returns a TranslatedQuery object which contains the translated query and the
	 * cql-related options.
	 * 
	 * @param queryRoot
	 *            Pre-parsed representation of the cql query
	 * @param valueTransformerMap
	 *            callbacks which allow us to normalize field values when we know about them
	 * @return TranslatedQuery object which contains the translated query and the cql-related options
	 * @throws CQLParseException
	 * @throws IOException
	 */
	public TranslatedQuery getTranslatedQuery(final String cqlQuery, CqlValueTransformerMap valueTransformerMap) throws CQLParseException, IOException;

	/**
	 * method performs the translation and returns a TranslatedQuery object which contains the translated query and the
	 * cql-related options.
	 * 
	 * @param queryRoot
	 *            Pre-parsed representation of the cql query
	 * @param valueTransformerMap
	 *            callbacks which allow us to normalize field values when we know about them
	 * @param options
	 *            options that modify the behavior of cql parsing
	 * @return TranslatedQuery object which contains the translated query and the cql-related options
	 * @throws CQLParseException
	 * @throws IOException
	 */
	public TranslatedQuery getTranslatedQuery(final String cqlQuery, CqlValueTransformerMap valueTransformerMap, Map<String, List<String>> options)
			throws CQLParseException, IOException;

	/**
	 * Translates a cql query in a mongodb query.
	 * @param cqlQuery
	 *          the query to be translated.
	 * @return
	 *          a mongodb query expressed as org.bson.conversions.Bson object.
	 */
	public Bson toMongo(final String cqlQuery) throws IOException, CQLParseException;

}
