package searchengine;
import java.io.*;
import java.net.*;
import java.sql.*;

/**
   This bean searches for similar web pages to user given webpage URL
*/
public class SearchResultBean
{
   private int[] count_results;
   private boolean next_url;
   private boolean valid_url;
   private boolean match_found;   
   private String user_url;
   private String message;
   private String output_message;
   private String similar_pages;
   private ResultSet result;
   private Statement stat;
   private Connection conn = null;
   private String[] dbKeyColumns = {"java", "basic", "begin", "object", "class", "tutorial",
                                  "encapsulation", "hiding", "modularity", "abstraction",
                                  "polymorphism", "overloading", "exception_handling",
                                  "exception", "packages", "inheritance", "class_hierachies",
                                  "polymorphic_ref", "applet", "gui", "abstract_class", 
                                  "interface"};

   private String[] mykeywords = {"java", "basic", "begin", "object", "class", "tutorial",
                                  "encapsulation", "hiding", "modularity", "abstraction",
                                  "polymorphism", "overloading", "exception handling",
                                  "exception", "packages", "inheritance", "class hierachies",
                                  "polymorphic reference", "applet", "gui", "abstract class", 
                                  "interface"};

   /**
      Constructor
   */
   public SearchResultBean()
   {
      setOutput_message("");      
      similar_pages = "";
      valid_url = false;
   }

   /**
      Read-only user_url property
      @return the user given webpage URL
   */
   public String getUser_url()
   {
      return user_url;
   }
   
   /**
      Write-only user_url property
      @param input_url the the user given webpage URL
   */
   public void setUser_url(String input_url) throws Exception
   {
      user_url = input_url;

      /* Checks for URL validity and saves to file */
      savePage();

      if (valid_url)
      {
         try
         {
            /* Connect to search_db database */
            conn = DataSourceBean.getConnection();

            /* Create SQL statement object */
            stat = conn.createStatement();

            /*
               Checks if page is already in database, if not
               it counts the keywords and inserts into database
            */
            processPage();

            /* Checks database for similar pages */      
            processSimilarPages();
         }
         finally
         {
            if (conn != null) conn.close();
         }

      } /* End if (valid_url) */

   } /* End method setUser_url */
   
   /**
      Read-only output_message property
      @returns output_message with regards to whether url link is valid
   */
   public String getOutput_message()
   {
      return output_message;
   }
   
   /**
      Write-only output_message property
      @param input_msg the output message to report
   */
   public void setOutput_message(String input_msg)
   {
      output_message = input_msg;
   }

   /**
      Read-only result property
      @returns result 
   */
   public ResultSet getResult()
   {
      return result;
   }

   /**
      Write-only result property
      @param input_result to set result property
   */
   public void setResult(ResultSet input_result) 
   {
      result = input_result;
   }

   /**
      Read-only similar_pages property
      @returns similar_pages 
   */
   public String getSimilar_pages()
   {
      return similar_pages;
   }
   
   /**
      Write-only similar_pages property
      @param input_pages the output urls to report
   */
   public void setSimilar_pages()throws SQLException
   {
      similar_pages = result.getString("URL").trim();
   }

   /**
      Read-only next_url property
      @returns next_url 
   */
   public boolean isNext_url()
   {
      return next_url;
   }
   
   /**
      Write-only next_page property
      @param input_value to set whether next_url is valid
   */
   public void setNext_url() throws SQLException
   {
      next_url = result.next();
   }

   /**
      Read-only match_found property
      @returns match_found 
   */
   public boolean isMatch_found()
   {
      return match_found;
   }
   
   /**
      Write-only match_found property
      @param input_value to set whether next_url is valid
   */
   public void setMatch_found(boolean input_value)
   {
      match_found = input_value;
   }


   /**
      Checks if URL is valid and if valid saves webpage to a file
   */
   public void savePage() throws IOException
   {
      URL u;
      int code;
      boolean done;
      String file_input;
      FileWriter writer;
      PrintWriter out;

      valid_url = false;
      try
      {
         /* Open connection */
         u = new URL(user_url);
         URLConnection connection = u.openConnection();

         /* Check whether response code is HTTP_OK (200) */
         HttpURLConnection httpConnection = (HttpURLConnection)connection;

         code = httpConnection.getResponseCode();

         if (code != httpConnection.HTTP_OK)
         {
            switch(code)
            {
               case 404: setOutput_message(code + ": Page Not Found"); 
                         break;
               default: setOutput_message(code + " " + httpConnection.getResponseMessage());
                        break;
            }
         }
         else
         {
            valid_url = true;

            /* Retrieve web page and place into file (C:\jakarta-tomcat-5.0.19\bin) */
            writer = new FileWriter("inputpage.txt");
            out = new PrintWriter(writer);

            /* Get stream */
            InputStream in = connection.getInputStream();

            /* Turns stream into reader */
            BufferedReader reader = new BufferedReader(new InputStreamReader(in));

            /* Read server response and write to file*/
            done = false;
            while (!done)
            {
               file_input = reader.readLine();
               if (file_input == null)
                  done = true;
               else
                  out.println(file_input);
            }
            writer.close();
         } /* End HTTP_OK */
      }
      catch (MalformedURLException exception)
      {
         setOutput_message("Invalid url format. Don't forget http://.");
      }
      catch (UnknownHostException exception)
      {
         setOutput_message("Unknown Host. Please check URL syntax.");
      }
      catch (ConnectException exception)
      {
         setOutput_message("Connection timed out.");
      }      

   } /* End method savePage */


  /**
     Checks if page is already in database, if not
     it counts the keywords and inserts into database
  */
   public void processPage() throws Exception
   {
      int i;
      String sql_string;
      ResultSet result;


      /* Check if url already exists in database */
      result = stat.executeQuery("SELECT * FROM keyword_cnt where url='" +
                                 user_url + "';");

      /* URL already exists in database */
      if (result.next())
      {
         count_results = new int[mykeywords.length];
           
         /* Extract keyword count values from database for this URL */
         for (i = 0; i < mykeywords.length; i++)
         {
            count_results[i] = result.getInt(dbKeyColumns[i]);
         }         
      }
      else /* URL does not exist in database */
      {
         /* Strip off HTML tags */
         WordCounter.stripHTML("inputpage.txt");

         /* Count keywords */
         count_results = WordCounter.count("pagestrip.txt", mykeywords);

         sql_string = "INSERT INTO keyword_cnt VALUES (\"" + user_url + "\", ";

         /* Write SQL statement to store values in database */
         for (i = 0; i < count_results.length; i++)
         {
            if (i == count_results.length - 1)
               sql_string = sql_string + count_results[i] + ");"; 
            else
               sql_string = sql_string + count_results[i] + ", "; 
         }

         /* Store url and it's keyword count values in database */
         stat.execute(sql_string);
      }

   } /* End method processPage */

   /**
      Searches database for similar pages
   */
   public void processSimilarPages() throws SQLException
   {
      int i;
      String query_string;
      String weight_string;

      /* Query string for calculating weights */
      weight_string = "(";
      for (i = 0; i < count_results.length; i++)
      {
         if (i == count_results.length - 1)
            weight_string = weight_string + "(" + dbKeyColumns[i] + "*" + count_results[i] + ")) ";
         else
            weight_string = weight_string + "(" + dbKeyColumns[i] + "*" + count_results[i] + ") + ";
      }

      query_string = "SELECT url, " + weight_string + " AS weight FROM keyword_cnt " + 
                     "WHERE " + weight_string + " != 0 AND url !='" + user_url + "' " + 
                     "ORDER BY weight DESC;";

      setResult(stat.executeQuery(query_string));

      if (!result.next())
         setMatch_found(false);
      else
         setMatch_found(true);

   } /* End method getSimilarPages */

} /* End class SearchResultBean */