/*
   This client uses Java's "high level" abstractions
   for communicating with an HTTP server, the URL
   and URLConnection classes.
   See
      https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/URL.html
      https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/net/URLConnection.html

   Java's "high level" abstraction takes care of creating a socket,
   making the connection with the server, sending the HTTP request
   with the appropriate request headers, getting the HTTP repsonse
   and the reponse headers, getting the response entity body (which
   is the resource that we want) and finally closing and releaseing
   the scocket. After the communication with the server is closed,
   then the abstraction gives us access to the resource data that
   we requested.

   Notice somethig important. When we ask the url connection for
   an input stream. we are not getting the socket's stream that was
   connected to the server. Instead, we are getting an input stream
   that is "connected" to the buffer into which the url connection
   downloaded the resource data we requested. The stream is more than
   likely an instance of Java's StringReader class.
      https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/io/StringReader.html

   This client takes a URL as an optional command-line argument.
*/

import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.IOException;
import java.net.URL;
import java.net.URLConnection;
import java.net.MalformedURLException;

public class HttpClient_v3
{
   public static void main (String[] args)
   {
      final String resourceURL;
      if (args.length > 0)
      {
         resourceURL = args[0];
      }
      else
      {
         resourceURL = "http://localhost:8080/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 );


      // Send a request to the server.
      System.out.println("CLIENT: retrieving resource: " + resourceURL );
      try
      {
         final URL url = new URL(resourceURL);
         final URLConnection connection = url.openConnection();

         System.out.println("CLIENT: connection established, waiting...");
         try{Thread.sleep(5_000);}catch(InterruptedException e){}

         // Get a stream connected to the server's response body.
         final BufferedReader in = new BufferedReader(
                                     new InputStreamReader(
                                        connection.getInputStream(), "latin1"));
                                        //url.openStream(), "latin1"));

         System.out.println("CLIENT: requested input stream, waiting...");
         try{Thread.sleep(5_000);}catch(InterruptedException e){}

         System.out.println("CLIENT: reading response body.");

         // Read just the server's response body.
         for (String oneLine; (oneLine = in.readLine()) != null; )
         {
            System.out.println(oneLine);
         }
         in.close();
      }
      catch (MalformedURLException e)
      {
         System.out.println(e);
      }
      catch (IOException e)
      {
         System.out.println("CLIENT: Error occurred while retrieving URL.");
         System.out.println(e);
      }
   }
}
