/*
   This client implements only the HTTP GET method.

   This client takes three, optional, command-line arguments,
      hostname  port  path

   This client defaults to connecting to the
   local web server defined in this folder.
*/

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.PrintWriter;
import java.io.IOException;
import java.net.UnknownHostException;
import java.net.InetAddress;
import java.net.Socket;

public class HttpClient_v1
{
   private static final int SERVER_PORT = 8080;

   public static void main (String[] args)
   {
      final String hostName;
      if (args.length > 0)
      {
         hostName = args[0];
      }
      else
      {
         hostName = "localhost";
      }

      final int portNumber;
      if (args.length > 1)
      {
         portNumber = Integer.parseInt(args[1]);
      }
      else
      {
         portNumber = SERVER_PORT;
      }

      final String path;
      if (args.length > 2)
      {
         path = args[2];
      }
      else
      {
         path = "/static.html";
      }

      // Get this client's process id number (PID). This helps
      // to identify the client in TaskManager or TCPView.
      final ProcessHandle handle = ProcessHandle.current();
      final long pid = handle.pid();
      System.out.println("CLIENT: Process ID number (PID): " + pid );

      // Get the name and IP address of the local host and
      // print them on the console for information purposes.
      try
      {
         final InetAddress address = InetAddress.getLocalHost();
         System.out.println("CLIENT: Hostname: " + address.getCanonicalHostName() );
         System.out.println("CLIENT: IP address: " +address.getHostAddress() );
      }
      catch (UnknownHostException e)
      {
         System.out.println("Unable to determine this client's address.");
         System.out.println( e );
      }

      // Make a connection to the server.
      Socket         socket = null;
      BufferedReader in = null;
      PrintWriter    out = null;
      try
      {
         System.out.println("CLIENT: Connecting to server: " + hostName
                          + " on port " + portNumber );

         socket = new Socket(InetAddress.getByName(hostName),
                             portNumber);

         in = new BufferedReader(
                  new InputStreamReader(
                       socket.getInputStream()));

         out = new PrintWriter(socket.getOutputStream());
      }
      catch (IOException e)
      {
         System.out.println("CLIENT: Cannot connect to server.");
         e.printStackTrace();
         System.exit(-1);
      }
      System.out.println("CLIENT: Connected to server.");
      // Get this client's local port number and log it to the console.
      // This helps to identify this client in the server's transcript.
      final int port = socket.getLocalPort();
      System.out.println("CLIENT: Local Port: " + port);


      // Implement the HTTP client/server application level protocol.
      // Send the server an HTTP request.
             out.println( "GET " + path + " HTTP/1.1");
      System.out.println("<GET " + path + " HTTP/1.1");
             out.println( "Host: " + hostName + ":" + portNumber);
      System.out.println("<Host: " + hostName + ":" + portNumber);
             out.println( "Connection: close");
      System.out.println("<Connection: close");
             out.println(); // The sentinel value that marks the end of the http headers.
      System.out.println("<");
             out.flush();

      // Receive the HTTP response from the server (including the response headers).
      try
      {
         String oneLine;
         // Read the response headers.
         while ( (oneLine = in.readLine()) != null )
         {
            System.out.println(">" + oneLine);
            if ( oneLine.isEmpty() )
            {
               break;
            }
         }
         // Read the entity body.
         while ( (oneLine = in.readLine()) != null ) // Read to eof. This is not really correct.
         {
            System.out.println(oneLine);
         }
      }
      catch (IOException e)
      {
         System.out.println("CLIENT: Cannot receive response from server.");
         System.out.println( e );
      }

      // Disconnect from the server.
      try
      {
         socket.close();
         System.out.println("CLIENT: Closed socket.");
      }
      catch (IOException e)
      {
         System.out.println("CLIENT: Cannot disconnect from server.");
         System.out.println( e );
      }
   }
}
