
import java.util.*;
import java.io.*;
import java.net.*;

// OAA
import com.sri.oaa2.com.*;
import com.sri.oaa2.lib.*;
import com.sri.oaa2.icl.*;
import com.sri.oaa2.guiutils.*;
import com.sri.oaa2.pp.*;

// Google's Library.
import com.google.soap.search.*;

/*
OAA wrapper for Google

Peter Jarvis, January 2003.

Report Bugs to Jarvis@ai.sri.com
*/

public class oaaGoogle
{
  private oaaGoogle theAgent;

   // OAA Declerations
  public LibOaa oaa;
  private static boolean debug = true;
  private static boolean run = true;
  private static String defaultHost = "localhost";
  private static String defaultPort = "3378";
  private static String googleSearchQuery ="google_search";
  private static String googleCachedPage ="google_cached_page";
  private static String googleSpellQuery ="google_spell";


  // query defaults.
  private static String agentName = "Google Agent";

 public oaaGoogle (String[] args) {
   // connect to OAA.
   oaaInit(args);
 }


 private boolean oaaInit (String[] args) {

   debugMessage("Making OAA Connection:");
   //system.out.println("Args "+args[0] + " " + args[1] + " " + args[3]);


   /* Create instance of OAA library using TCP as protocol */
   oaa = new LibOaa(new LibCom(new LibComTcpProtocol(),args));

   /* Connect to the facilitator using the host/port defined in file "setup.pl" */
   if (!oaa.getComLib().comConnect("parent",IclUtils.icl("tcp(A,B)"),(IclList)IclUtils.icl("[]")))
     {
        System.out.println("Couldn't connect to facilitator");
          return false;
     }



   /* Register my agent info along the connection  */

    IclList solvables = new IclList();
    solvables.iclAddToList(IclUtils.icl(googleSearchQuery+"(GoogleLicenceKey,Query, NoResults, ResultTitle, ResultURL, ResultSnippet)"));
    solvables.iclAddToList(IclUtils.icl(googleCachedPage+"(GoogleLicenceKey,URL,Page)"));
    //solvables.iclAddToList(IclUtils.icl(googleSpellQuery+"(Query)"));

    if(!oaa.oaaRegister("parent",
                         agentName,
                         solvables,
                         new IclList())) {
           throw new RuntimeException("Error: Could not register solvables");
    }

    oaa.oaaRegisterCallback("oaa_AppDoEvent",
			    new OAAEventListener() {
				public boolean doOAAEvent(IclTerm goal,
							  IclList params,
							  IclList answers)
				{
				  return(processMessage(goal, params, answers));
				}
			      }
			    );




    /* Let the Facilitator know I'm finished with any initialization and ready to participate
       as a member of the agent community.
    */

    System.out.println("OAA facilitator registration completed.");
    oaa.oaaReady(true);
    return true;
 }


 public boolean processMessage(IclTerm goal, IclList params, IclList answers)
  {
   String functor = new String("");

   if(goal.isStruct()) {
      functor = ((IclStruct) goal).getFunctor();
   }


   if (functor.equals(googleSearchQuery)) {
      debugMessage("Processing Request: " + functor);
      return processSearchQuery(goal,
                          answers);
   }else if (functor.equals(googleCachedPage)) {
        debugMessage("Processing Request: " + functor);
        return processCachedPageQuery(goal,
                          answers);
   } else {
      // Unknown solvable case
       System.out.println("Error, unknown solvable"+ functor);
       answers.iclAddToList(goal);
       return false;
    }
  }


 private boolean processSearchQuery( IclTerm goal,
                                     IclList answers) {


   // googleSearchQuery+"(GoogleLicenceKey,Query, NoResults, ResultTitle, ResultURL, ResultSnippet)"));
   String googleLicenceKey = goal.getTerm(0).toString();
   String theQuery = goal.getTerm(1).toString();
   String noResultsString = goal.getTerm(2).toString();

   googleLicenceKey = com.sri.oaa2.icl.IclUtils.removeQuotes(googleLicenceKey);
   theQuery = com.sri.oaa2.icl.IclUtils.removeQuotes(theQuery);
   noResultsString = com.sri.oaa2.icl.IclUtils.removeQuotes(noResultsString);

   Integer noResultsInteger = new Integer(noResultsString);

    try {
      // Create a Google Search object, set our authorization key
      GoogleSearch s = new GoogleSearch();
      s.setKey(googleLicenceKey.toString());
      s.setMaxResults(noResultsInteger.intValue());
      // Set the search
      s.setQueryString(theQuery.toString());

      // Do the search.
      debugMessage("About to send query to Google");
      GoogleSearchResult r = s.doSearch();
      debugMessage("Google Result");
      debugMessage(r.toString());

      // proceess and package results.

      GoogleSearchResultElement results [] = r.getResultElements();

      for (int counter = 0; counter < results.length; ++counter) {
         GoogleSearchResultElement result = results[counter];
         String returnResult = googleSearchQuery+"("+goal.getTerm(0) +","
                               + goal.getTerm(1) +","
                               + goal.getTerm(2) +",'"
                               + IclUtils.doubleQuotes(result.getTitle()) +"','"
                               + IclUtils.doubleQuotes(result.getURL()) +"','"
                               + IclUtils.doubleQuotes(result.getSnippet())+"')";

          System.out.println("Return Result");
          System.out.println (returnResult);


          IclTerm resultAsTerm = IclUtils.iclNewTermFromString(returnResult);
          answers.iclAddToList(resultAsTerm);
       }

    } catch (GoogleSearchFault f) {
      System.out.println("The call to the Google Web APIs failed:");
      System.out.println(f.toString());
      return false;
    }

   return true;
 }

 private boolean processCachedPageQuery(IclTerm goal,
                                        IclList answers) {

   // (googleCachedPage+"(GoogleLicenceKey,URL,Page)"));

   String googleLicenceKey = goal.getTerm(0).toString();
   String theQuery = goal.getTerm(1).toString();
   googleLicenceKey = com.sri.oaa2.icl.IclUtils.removeQuotes(googleLicenceKey);
   theQuery = com.sri.oaa2.icl.IclUtils.removeQuotes(theQuery);



   try {
     // Create a Google Search object, set our authorization key
     GoogleSearch s = new GoogleSearch();
     s.setKey(googleLicenceKey.toString());
     debugMessage("Requesting Cached Page from Google: " + theQuery.toString());
      // Set the search
      byte [] cachedBytes = s.doGetCachedPage(IclUtils.removeQuotes(theQuery.toString()));
      // Note - this conversion to String should be done with reference
      // to the encoding of the cached page, but we don't do that here.
      debugMessage("Google Replied");
      String cachedString = new String(cachedBytes);

      debugMessage(cachedString);

     // IclTerm page = IclUtils.iclNewTermFromString("'"+cachedString+"'");

      cachedString = IclUtils.doubleQuotes(cachedString);

      String returnResult = googleCachedPage+"("+goal.getTerm(0) + ","
                                                +goal.getTerm(1) +",'"+ cachedString +"')";

      IclTerm resultAsTerm = IclUtils.iclNewTermFromString(returnResult);
      answers.iclAddToList(resultAsTerm);

    } catch (GoogleSearchFault f) {
      System.out.println("The call to the Google Web APIs failed:");
      System.out.println(f.toString());
      return false;
    }

     return true;
 }

 private boolean processSpellingQuery(IclTerm goal,
                                      IclList answers) {

   return true;

 }



 // we only output debug messages when the global debug is set to true.
 private static void debugMessage (String message) {
    if (debug) {
     System.out.println(message);
   }
 }

 	public static void main(String argv[])
        {
                System.out.println("");
                System.out.println("");
                System.out.println("OAA Google Query Agent Agent v0.0.");
                System.out.println("(C) SRI International, 2002");
                System.out.println("");
                System.out.println("Search engine provided by Google Inc.");
                System.out.println("");
                System.out.println("Report bugs to: Jarvis@ai.sri.com");
                System.out.println("---------------------------------");

                    // parse arguments.

                int max =argv.length;
                for (int counter = 0; counter < max; counter++) {
                  String currentArgument = argv[counter];
                  if (currentArgument.compareTo("-help") == 0) {
                     System.out.println("usage: ASCS [options]");
                     System.out.println("where,");
                     System.out.println(" -oaa_host <host> = sets the OAA facilitator's hostname");
                     System.out.println(" -oaa_port <port> = sets the OAA faciltitaor's port number");
                     System.out.println(" -debug = turns on debug messages");
                     System.out.println(" -help = display this help text");
                     run = false;
                  } else if (currentArgument.compareTo("-debug") == 0) {
                     debug = true;
                     debugMessage("Debugging Mode");
                  }

                }

                if (run) {

                  oaaGoogle theAgent = new oaaGoogle(argv);
                  debugMessage("Agent Ready...");

                  // loop, but sleep this thread to let other processes get the machine.
                  Thread thisThread = Thread.currentThread();
                  while (true) {
                     try {
                        thisThread.sleep(1200);
                     } catch (InterruptedException e){
                     }

                  }
                }
	}

}





