package example.indexsearch;

import java.util.Date;

import org.sourceforge.beanindex.BeanIndex;
import org.sourceforge.beanindex.Index;
import org.sourceforge.beanindex.search.BeanIndexSearcher;
import org.sourceforge.beanindex.search.Hits;
import org.sourceforge.beanindex.search.IndexField;
import org.sourceforge.beanindex.search.Query;
import org.sourceforge.beanindex.search.SearchTerm;

import org.sourceforge.beanindex.search.SearcherConfigInfo;

import example.indexbuild.BuildExample;
import example.util.DigitalItemBean;

public class SearchExample {
    private String[] searchTerms = "man and sea""nature or mountain",
            "boy not girl""(sea or lake) not river""technology",
            "flower or tree", BuildExample.INDEX_NAME };

    private BeanIndexSearcher beanIndexSearcher = null;

    private Index[] indeces = null;

    private IndexField[] searchableFields = null;

    public static void main(String[] argsthrows Exception {
        SearchExample instance = new SearchExample();
        instance.initialize();
        instance.search();
    }

    private void initialize() throws Exception {
        String path = null// null defaults to current working directory.
        BeanIndex beanIndex = new BeanIndex(path);
        // It is advisable to deploy now. If there is any new index dataset
        // placed in deploy directory
        beanIndex.deploy();
        SearcherConfigInfo configInfo = new SearcherConfigInfo();
        configInfo.setDataCacheEnabled(true)// enables Bean Cache
        configInfo.setIndexCacheEnabled(true)// enables Index node cache
        configInfo.setThreadPoolEnabled(true)// for multithreaded searching        
        configInfo.setDataCacheMaxSize(5000)// Bean Cache size
        configInfo.setIndexCacheMaxSize(2000)// Index node cache size
        configInfo.setThreadPoolMaxSize(20)// max thread pool size
        beanIndexSearcher = beanIndex.getBeanIndexSearcher(configInfo);
        // get all the indeces as views
        indeces = beanIndexSearcher.getAllIndexViews();
        // get all the indexed fields
        searchableFields = beanIndexSearcher.getAllIndexedFields();

    }

    private void search() throws Exception {
        SearchTerm item = null;
        Date start = new Date();
        for (int i = 0; i < this.searchTerms.length; i++) {
            Query request = beanIndexSearcher.createSearchRequest();
            request.addIndex(indeces[0]);
            // the following if block is for demonstration purpose only.
            if (searchTerms[i].equals(BuildExample.INDEX_NAME)) {
                // index buffer is directly returned.
                // easy way to get all the bean ids in an index file.
                // This method utilizes the feature that each index file has a
                // record which contains
                // all the beans that are added to this index name.
                request.setIndexBufferDirectRead(true);
            }
            for (int j = 0; j < searchableFields.length; j++) {
                // This example searches only keywords field of the bean
                if (searchableFields[j].getName().toLowerCase().equals("keywords")) {
                    item = new SearchTerm(searchableFields[j]);
                    item.setSearchValue(searchTerms[i]);
                    request.addItem(item);
                }
            }
            Hits result = beanIndexSearcher.search(request);
            // retrieve the hits for a given index
            int index1Hits = result.getHitCount(indeces[0]);
            // get the total hits in this result
            int totalSize = result.getTotalHitCount();
            System.out.println(" Search Term = "+ searchTerms[i" Number of Hits = "+ totalSize);
            int length = (totalSize > 25 25 : totalSize);
            // get the beans 
            Object[] pageItems = result.getBeans(indeces[0]0, length);
            
            for(int k = 0; k < pageItems.length; k++) {
                DigitalItemBean bean = (DigitalItemBeanpageItems[k];
               //do something with bean
            }
            
        }
        Date end = new Date();
        this.printTimeReport(start.getTime(), end.getTime());
    }

    /**
     * Prints the time taken for processing
     
     @param start
     @param end
     */
    private void printTimeReport(long start, long end) {
        end = end - start;
        long minute = (int) (end / 60000);
        long sec = (int) ((end - minute * 600001000);
        long mill = end - minute * 60000 - sec * 1000;
        System.out.println(" Process completed in :  " (minute" Minutes "
                (sec" seconds " + mill + " millisecs");
    }
}