package opennlp.tools.similarity.apps.solr;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;

import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;

import opennlp.tools.similarity.apps.HitBase;
import opennlp.tools.similarity.apps.RelatedSentenceFinder;
import opennlp.tools.similarity.apps.RelatedSentenceFinderML;
import opennlp.tools.similarity.apps.utils.Pair;
import opennlp.tools.textsimilarity.ParseTreeChunk;
import opennlp.tools.textsimilarity.ParseTreeChunkListScorer;
import opennlp.tools.textsimilarity.SentencePairMatchResult;
import opennlp.tools.textsimilarity.chunker2matcher.ParserChunker2MatcherProcessor;

import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryparser.classic.ParseException;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.CachingWrapperFilter;
import org.apache.lucene.search.Collector;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.QueryWrapperFilter;
import org.apache.lucene.search.ScoreDoc;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.params.CommonParams;
import org.apache.solr.common.params.ModifiableSolrParams;
import org.apache.solr.common.params.ShardParams;
import org.apache.solr.common.params.SolrParams;
import org.apache.solr.common.util.NamedList;
import org.apache.solr.handler.component.SearchHandler;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;



public class ContentGeneratorRequestHandler extends SearchHandler {
	private static Logger LOG = Logger
			.getLogger("com.become.search.requestHandlers.SearchResultsReRankerRequestHandler");
	private ParserChunker2MatcherProcessor sm = null;


	public void handleRequestBody(SolrQueryRequest req, SolrQueryResponse rsp){

		String query = req.getParams().get("q");
		LOG.info(query);

		String[] runCommand = new String[12], runInternal = new String[8];
		runCommand[0] = "java";
		runCommand[1] = "-Xmx1g";
		runCommand[2] = "-jar";
		runCommand[3] = "pt.jar";
		runCommand[4] = "\""+query+"\"";
		runCommand[5] = req.getParams().get("email");
		runCommand[6] = req.getParams().get("resourceDir");
		runCommand[7] = req.getParams().get("stepsNum");
		runCommand[8] = req.getParams().get("searchResultsNum");
		runCommand[9] = req.getParams().get("relevanceThreshold");
		runCommand[10] = req.getParams().get("lang");
		runCommand[11] = req.getParams().get("bingKey");

		for(int i= 0; i<8; i++){
			runInternal[i] = runCommand[i+4];
		}
		String resultText = null;
		try {
			resultText = cgRunner(runInternal);
		} catch (Exception e1) {
			
/*
		Runtime r = Runtime.getRuntime();
		Process mStartProcess = null;
		String workDir = req.getParams().get("workDir"); 
		if (workDir == null)
			System.err.println("workDir = null");

		try {
			mStartProcess = r.exec(runCommand, null, new File(workDir));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		StreamLogger outputGobbler = new StreamLogger(mStartProcess.getInputStream());
		outputGobbler.start();
		}
*/
		}
		
		NamedList<Object> values = rsp.getValues();
		values.remove("response");
		values.add("response", "We completed your request to write an essay on '"+query+"' and sent you an email at "+ runCommand[5]);
		values.add("text", resultText);
		rsp.setAllValues(values);

	}


	class StreamLogger extends Thread{

		private InputStream mInputStream;

		public StreamLogger(InputStream is) {
			this.mInputStream = is;
		}

		public void run() {
			try {
				InputStreamReader isr = new InputStreamReader(mInputStream);
				BufferedReader br = new BufferedReader(isr);
				String line = null;
				while ((line = br.readLine()) != null) {
					System.out.println(line);
				}
			} catch (IOException ioe) {
				ioe.printStackTrace();
			}
		}
	}

	public String cgRunner(String[] args) {
		ParserChunker2MatcherProcessor sm = null;
		int count=0; 
		for(String a: args){
			System.out.print(count+" >> " + a);
			count++;
		}
		

		try {
			String resourceDir = args[2];
			if (resourceDir!=null)
				sm = ParserChunker2MatcherProcessor.getInstance(resourceDir);
			else
				sm = ParserChunker2MatcherProcessor.getInstance();

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		String bingKey = args[7];
		if (bingKey == null){
			bingKey = //"e8ADxIjn9YyHx36EihdjH/tMqJJItUrrbPTUpKahiU0=";
					"xdnRVcVf9m4vDvW1SkTAz5kS5DFYa19CrPYGelGJxnc";
		}

		RelatedSentenceFinder f = null;
		String lang = args[6];
		if (lang.startsWith("es")){
			f = new RelatedSentenceFinderML(Integer.parseInt(args[3]), Integer.parseInt(args[4]), Float.parseFloat(args[5]), bingKey);
			f.setLang(lang);
		} else	    

			if (args.length>4 && args[4]!=null)
				f = new RelatedSentenceFinder(Integer.parseInt(args[3]), Integer.parseInt(args[4]), Float.parseFloat(args[5]), bingKey);
			else
				f = new RelatedSentenceFinder();
		String generatedContent = null;
		List<HitBase> hits = null;
		try {

			hits = f.generateContentAbout(args[0].replace('+', ' ').replace('"', ' ').trim());
			System.out.println(HitBase.toString(hits));
			generatedContent = HitBase.toResultantString(hits);

			opennlp.tools.apps.utils.email.EmailSender s = new opennlp.tools.apps.utils.email.EmailSender();

			try {
				s.sendMail("smtp.rambler.ru", "bg7550@rambler.ru", "pill0693", new InternetAddress("bg7550@rambler.ru"), new InternetAddress[]{new InternetAddress(args[1])}, new InternetAddress[]{}, new InternetAddress[]{}, 
						"Generated content for you on '"+args[0].replace('+', ' ')+"'", generatedContent, null);
			} catch (AddressException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (Exception e) {

				e.printStackTrace();
				try {
					s.sendMail("smtp.rambler.ru", "bg7550@rambler.ru", "pill0693", new InternetAddress("bg7550@rambler.ru"), new InternetAddress[]{new InternetAddress(args[1])}, new InternetAddress[]{}, new InternetAddress[]{}, 
							"Generated content for you on '"+args[0].replace('+', ' ')+"'", generatedContent, null);
				} catch (Exception e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}


		} catch (Exception e) {
			e.printStackTrace();
		}
		return generatedContent;
	}

	
}

/*
http://173.255.254.250:8983/solr/contentgen/?q=human+body+anatomy&email=bgalitsky@hotmail.com&resourceDir=/home/solr/solr-4.4.0/example/src/test/resources&workDir=/home/solr/solr-4.4.0/example/solr-webapp/webapp/WEB-INF/lib&stepsNum=20&searchResultsNum=10&relevanceThreshold=1.5

 */