/**
 * Created on Jul 3, 2005
 * $id:  $
 */
package org.jvnet.lookout.google.web.adapter;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.jvnet.lookout.core.adapter.CannotSearchException;
import org.jvnet.lookout.core.adapter.SearchExecutor;
import org.jvnet.lookout.core.model.SearchQuery.Parameter;
import org.jvnet.lookout.core.util.Utilities;
import org.jvnet.lookout.google.web.Plugin;
import org.jvnet.lookout.google.web.preference.Preferences;

import com.google.soap.search.GoogleSearch;
import com.google.soap.search.GoogleSearchFault;
import com.google.soap.search.GoogleSearchResult;
import com.google.soap.search.GoogleSearchResultElement;

public class WebSearchExecutor implements SearchExecutor {
	
	private String userKey = null;
	private static org.eclipse.core.runtime.Preferences searchCorePreferences;
	private static org.eclipse.core.runtime.Preferences searchWebPreferences;
	
	public WebSearchExecutor() {
		
		searchCorePreferences = org.jvnet.lookout.core.Plugin.getDefault().getPluginPreferences();
		searchWebPreferences = Plugin.getDefault().getPluginPreferences();
	}
	
	public List executeSearch(String queryString, Map<Parameter, String> parameters) throws CannotSearchException {
		
		GoogleSearch googleSearch = new GoogleSearch();
		
		if(!Plugin.getDefault().getPluginPreferences().isDefault(Preferences.Key)) {
			//Read the the client specifc key    	
			userKey = searchWebPreferences.getString(Preferences.Key);			
		}
		
		if(userKey == null) {
			throw new CannotSearchException("Could not perform Google Web search. Make sure that you have specified the Google Web Search key in the preferences section.",
					Utilities.createPluginStatus(
							Plugin.getDefault(),
							//CXB_EXTERNALIZE
							"",
							IStatus.ERROR,
							new IllegalStateException("Google Web Search key has not been specified")) 
			);
		}
		
		googleSearch.setKey(userKey);
		googleSearch.setQueryString(queryString);
		int maxNumberOfResults = searchCorePreferences.getInt(org.jvnet.lookout.core.preference.Preferences.NumberOfResults);
		
		//Web search returns at the most 10 results
		if(maxNumberOfResults > 10) {
			//This is documented here:
			//http://www.google.com/apis/reference.html#2_7
			//See also:
			//http://www.google.com/apis/reference.html#2_1 see "maxResults"

			maxNumberOfResults = 10;
		}
		
		googleSearch.setMaxResults(maxNumberOfResults);
		
        //Find the batch number...
        int batchNumber = Integer.parseInt(parameters.get(Parameter.BATCH));	

        //Ensure that we start on the correct index... this is a zero based index..
		googleSearch.setStartResult((maxNumberOfResults * (batchNumber-1)));
		
		GoogleSearchResult searchResult = null;
		
		try {
			searchResult = googleSearch.doSearch();
		} catch (GoogleSearchFault e) {
			MultiStatus status = Utilities.createPluginStatus(
					Plugin.getDefault(),
					//CXB_EXTERNALIZE
					"Could not perform Google Web search",
					IStatus.ERROR,
					e
			);  
			
			//Log it...
			Plugin.getDefault().getLog().log(status);  
			
			throw new CannotSearchException(
					//CXB_EXTERNALIZE
					"Could not perform Google Web search.\n" +
					"Make sure that you have access to the internet.\n" + 
					"See error log for more details", 
					status);
		}
		
		GoogleSearchResultElement[] results = searchResult.getResultElements();
		
		List<GoogleSearchResultElement> resultsList = new ArrayList<GoogleSearchResultElement>(results.length);
		
		for (int i = 0; i < results.length; i++) {
			resultsList.add(results[i]);
		}
		
		return resultsList;
	}
}
