/*
Copyright (C) 2000-2010  Ministere de la culture et de la communication (France), AJLSM
See LICENCE file
*/
package fr.gouv.culture.sdx.search.lucene.query;

import java.io.IOException;
import java.util.ArrayList;

import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.Similarity;

import fr.gouv.culture.sdx.utils.Utilities;

/*Rasik Pandey rasik.pandey@ajlsm.com*/

/**Simple wrapper for a Lucene query that
 * collects all queries generated by calling
 * rewrite on the original Lucene query and stores
 * them in a BooleanQuery.
 *
 * A Searcher will call the rewrite() method
 * for each index and hence generate a query
 * containing terms for the respective index. This
 * class collects these queries so that they may be
 * used for highlighting, query expansion, etc. by
 * retrieving the underlying terms.
 *
 * @see #rewrite
 * @see #getRewrittenQueries
 * @see #getOriginalQuery
 */
public class CachingRewrittenQueryWrapper extends Query {
    protected org.apache.lucene.search.Query originalQuery = null;
    protected ArrayList rewrittenQueries = new ArrayList();

    public CachingRewrittenQueryWrapper(Query originalQuery) {
        this.originalQuery = originalQuery;
    }

    public BooleanQuery getRewrittenQueries() {
        BooleanQuery l_rewrittenQueries = Utilities.newBooleanQuery();
        for (int i = 0; i < rewrittenQueries.size(); i++) {
            Query rewrittenQuery = (Query) rewrittenQueries.get(i);
            // MAJ Lucene 2.1.0
            //l_rewrittenQueries.add(rewrittenQuery, false, false);
            l_rewrittenQueries.add(rewrittenQuery, BooleanClause.Occur.SHOULD);
        }
        return  l_rewrittenQueries;
    }

    public void resetRewrittenQueries() {
        this.rewrittenQueries = new ArrayList();
    }

    public Query getOriginalQuery() {
        return this.originalQuery;
    }

    public Query rewrite(IndexReader reader) throws IOException {
        Query rewrittenQuery = this.originalQuery.rewrite(reader);
        if (!this.rewrittenQueries.contains(rewrittenQuery))
            this.rewrittenQueries.add(rewrittenQuery);
        return rewrittenQuery;
    }

    public Query combine(Query[] queries) {
        return this.originalQuery.combine(queries);
    }

    public Similarity getSimilarity(Searcher searcher) {
        return this.originalQuery.getSimilarity(searcher);
    }

    protected void finalize() throws Throwable {
        super.finalize();
        //TODO maybe something here to ensure that all resources held by rewrittenQueries are cleaned up properly
    }

    public String toString() {
        return this.originalQuery.toString();
    }

    public String toString(String field) {
        return this.originalQuery.toString(field);
    }
}
