package org.dspace.newsletter;

import java.io.File;
import java.io.IOException;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import org.dspace.core.ConfigurationManager;

import org.apache.log4j.Logger;

import org.ibai.lucene.analysis.standard.StandardAnalyzer;
import org.ibai.lucene.document.Document;
import org.ibai.lucene.index.IndexReader;
import org.ibai.lucene.queryParser.ParseException;
import org.ibai.lucene.queryParser.QueryParser;
import org.ibai.lucene.search.*;
import org.ibai.lucene.store.FSDirectory;
import org.ibai.lucene.util.Version;

public class Searcher {

    private String sfecha;
    private Date fecha;
    private SimpleDateFormat formato = new SimpleDateFormat("yyyy-MM-dd");
    private IndexReader indexReader;
    private IndexSearcher searcher;
    private QueryParser titleQueryParser;
    private QueryParser contentQueryParser;
    
    private String INDEX_DIR = "";
    private final int DEFAULT_RESULT_SIZE = 100;
    private final String fs = System.getProperty("file.separator");
    
    private static final Logger log = Logger.getLogger(Searcher.class);
    
    
    public Searcher(String publicacion) throws IOException {
	INDEX_DIR = ConfigurationManager.getProperty("search.extended.dir") + fs + publicacion;
	indexReader = IndexReader.open(FSDirectory.open(new File(INDEX_DIR)));
	searcher = new IndexSearcher(indexReader);
	StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_36);
	titleQueryParser = new QueryParser(Version.LUCENE_36, IndexItem.FECHA, analyzer);
	contentQueryParser = new QueryParser(Version.LUCENE_36, IndexItem.CONTENIDO, analyzer);
    }
    
    
    public List<IndexItem> searchByContenido(String contenido){
        List<IndexItem> result = null;
        Searcher searcher;
        try {    
  	  result = findByContenido(contenido, DEFAULT_RESULT_SIZE);  
  	  close();
        } catch (Exception e) {
  	  log.error(e);
        }
        return result;
    }
    
    
    public List<IndexItem> search(String buscar, boolean ascendente) {
	List<IndexItem> result = null;
	Searcher searcher;
	try {
	    result = findByContenidoAll(buscar);
	    close();
	    IndexItemComparable iic = new IndexItemComparable();
	    if (ascendente) {
		iic.orden = 1;
	    } else {
		iic.orden = 2;
	    }
	    Collections.sort(result, iic);
	} catch (Exception e) {
	    log.error(e);
	}
	return result;
    }
    
    
    public List<IndexItem> searchByFile(String path) {
	List<IndexItem> result = null;
	Searcher searcher;
	try {
	    result = findByFichero(path, DEFAULT_RESULT_SIZE);
	    close();
	} catch (Exception e) {
	    log.error(e);
	}
	return result;
    }
    
    
    
    
    
    private List<IndexItem> findByContenido(String queryString, int numOfResults) throws ParseException, IOException {
	Query query = contentQueryParser.parse(queryString);
	ScoreDoc[] queryResults = searcher.search(query, numOfResults).scoreDocs;
	List<IndexItem> results = new ArrayList<IndexItem>();
	for (ScoreDoc scoreDoc : queryResults) {
	    Document doc = searcher.doc(scoreDoc.doc);
	    sfecha = doc.get(IndexItem.FECHA).substring(0, 4) + "-"
		    + doc.get(IndexItem.FECHA).substring(5, 7) + "-"
		    + doc.get(IndexItem.FECHA).substring(8, 10);
	    try {
		fecha = formato.parse(sfecha);
	    } catch (Exception e) {
		e.printStackTrace();
	    }
	    results.add(new IndexItem(fecha, doc.get(IndexItem.PATH), doc.get(IndexItem.CONTENIDO)));
	}
	return results;
    }
    
    
    
    
    
    private List<IndexItem> findByContenidoAll(String queryString) throws ParseException, IOException {
	Query query = contentQueryParser.parse(queryString);
	AllDocCollector col = new AllDocCollector();
	searcher.search(query, col);
	List<ScoreDoc> queryResults = col.getHits();
	List<IndexItem> results = new ArrayList<IndexItem>();
	for (ScoreDoc scoreDoc : queryResults) {
	    Document doc = searcher.doc(scoreDoc.doc);
	    sfecha = doc.get(IndexItem.FECHA).substring(0, 4) + "-"
		    + doc.get(IndexItem.FECHA).substring(5, 7) + "-"
		    + doc.get(IndexItem.FECHA).substring(8, 10);
	    try {
		fecha = formato.parse(sfecha);
	    } catch (Exception e) {
		e.printStackTrace();
	    }
	    results.add(new IndexItem(fecha, doc.get(IndexItem.PATH), doc.get(IndexItem.CONTENIDO)));
	}
	return results;
    }
    
    
    private List<IndexItem> findByFichero(String queryString, int numOfResults) throws ParseException, IOException {
	Query query = titleQueryParser.parse(queryString);
	ScoreDoc[] queryResults = searcher.search(query, numOfResults).scoreDocs;
	List<IndexItem> results = new ArrayList<IndexItem>();
	for (ScoreDoc scoreDoc : queryResults) {
	    Document doc = searcher.doc(scoreDoc.doc);
	    sfecha = doc.get(IndexItem.FECHA).substring(0, 4) + "-"
		    + doc.get(IndexItem.FECHA).substring(5, 7) + "-"
		    + doc.get(IndexItem.FECHA).substring(8, 10);
	    try {
		fecha = formato.parse(sfecha);
	    } catch (Exception e) {
		e.printStackTrace();
	    }
	    results.add(new IndexItem(fecha, doc.get(IndexItem.PATH), doc.get(IndexItem.CONTENIDO)));
	}
	return results;
    }
    
    
    private void close() throws IOException {
	searcher.close();
    }

}