import java.io.*;
import java.net.*;
import java.util.*;


/**
 * Handle an HTTP 1.0 connection in a new thread of execution
 *
 * This version:
 *
 *     Only supports GET requests
 *
 * @author  Prof. David Bernstein, James Madison University
 * @version 0.2
 */
public class HttpConnectionHandler implements Runnable
{
    private HttpInputStream  in;
    private HttpOutputStream out;    
    private MIMETyper        mimeTyper;
    private Socket           socket;


    /**
     * Explicit Value Constructor
     * (Starts the thread of execution)
     *
     * @param s    The TCP socket for the connection
     */
    public HttpConnectionHandler(Socket s)
    {
       socket = s;
       mimeTyper = MIMETyper.createInstance();
    }



    /**
     * The entry point for the thread
     */
    public void run()
    {
       HttpRequest     request;
       HttpResponse    response;
       InputStream     is;
       OutputStream    os;       
       String          method;

       try 
       {
          // Get the I/O streams for the socket
          is = socket.getInputStream();
          os = socket.getOutputStream();

          in  = new HttpInputStream(is);
          out = new HttpOutputStream(os);

          // Create an empty request and response
          response = new HttpResponse();
          request  = new HttpRequest();

          try
          {
             // Read and parse the request information
             request.read(in);


             // Determine the method to use
             method   = request.getMethod().toUpperCase();

             // Respond to the request
             if      ((request == null) || (method == null))
                response.sendError(HttpResponse.SC_BAD_REQUEST, out);
             else if (!method.equals("GET"))
                response.sendError(HttpResponse.SC_NOT_IMPLEMENTED, out);
             else 		
                doGet(request, response);
          }
          catch (Exception e)
          {
             response.sendError(HttpResponse.SC_BAD_REQUEST, out);
          }
       } 
       catch (IOException ioe) 
       {
          // I/O problem so terminate the thread.
          // The server should close the socket.
       }
    }


    /**
     * Handle the GET request
     *
     * @param request   Contents of the request
     * @param response  Used to generate the response
     */
    private void doGet(HttpRequest request, HttpResponse response)
    {
       byte[]             content;
       FileInputStream    fis;
       int                length;
       String             uri;

       // NOTE: We should check to make sure that the
       //       URI is in a "public" portion of the file system
       uri = "../public_html"+request.getRequestURI();

       try 
       {
          // Create a stream for the file
          // and determine its length
          fis = new FileInputStream(uri);
          length = fis.available();
          response.setStatus(HttpResponse.SC_OK);

          // Set the content type
          response.setContentType(mimeTyper.getContentTypeFor(uri));

          // Read the file
          content = new byte[length];
          fis.read(content);

          // Set the payload
          response.setContent(content);          

          //Write the response
          response.write(out);

          // Close the file
          fis.close();
       } 
       catch (IOException ioe) 
       {
          response.sendError(HttpResponse.SC_NOT_FOUND, out);
       }
    }

}
