// Written by Dr. Deborah Hwang for CS 350
// Pizza Server Thread that receives data from
// Pizza Order Form applications and sends back a response

import java.io.*;
import java.net.*;
import java.util.*;

class PizzaServerThread extends Thread 
{
   Socket socket;
   BufferedReader in;
   PrintWriter out, fileout;
   boolean DEBUG = true;

   public String toString() 
   {
      return "PizzaServerThread: socket = " + socket
             + "; in = " + in + "; out = " + out + "; fileout = " + fileout;
   }  // end toString

   PizzaServerThread(Socket socket) throws IOException 
   {
      super("PizzaServer");

      if (DEBUG)
      {
	 System.err.println("PizzaServerThread: constructor");
	 System.err.println("PizzaServerThread: setup socket streams");
      }

      in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
      out = new PrintWriter(socket.getOutputStream(), true);

      if (in == null) 
      {
         System.err.println("PizzaServerThread: Input stream seemed "
                             + "to be created successfully, but it's null.");
         throw new IOException();
      }  // end if

      if (out == null) 
      {
         System.err.println("PizzaServerThread: Output stream seemed "
                            + "to be created successfully, but it's null.");
         throw new IOException();
      }  // end if

      this.socket = socket;

      if (DEBUG)
	 System.err.println("PizzaServerThread: end constructor");
   }  // end constructor

   // entry point for thread, called by start()
   public void run() 
   {
      while (true)
      {
	 String name = null;
	 String address = null;
	 String size = null;
	 Vector toppings = null;
         try 
         {
            // Read data.
	    if (DEBUG)
	       System.err.println("PizzaServerThread: reading data");
            name = in.readLine();
            address = in.readLine();  // at least one line
            String addressLine = in.readLine();
            while (!addressLine.equals("AddrEnd"))
	    {
	       address = address + "\n" + addressLine;
	       addressLine = in.readLine();
            }  // end while reading address lines
            size = in.readLine();
            String topping = in.readLine();
            toppings = new Vector();
            while (!topping.equals("TopEnd"))
            {
               toppings.addElement(topping);
               topping = in.readLine();
            }  // end while reading toppings
	 }
         catch (Exception e) // Print out error message & exit
         { 
            System.err.println("PizzaServerThread: exception");
            e.printStackTrace();
	    System.exit (-1);
         }  // end catch

	 try
	 {
            // Construct message for both file and response
	    if (DEBUG)
	       System.err.println("PizzaServerThread: constructing message");
            String message = "Name : " + name;
            message = message + "\nAddress : " + address;
            message = message + "\nSize : " + size;
            message = message + "\nToppings : "; 
            for (int i = 0; i < toppings.size()-1; i++)
	       message = message + (String) toppings.elementAt(i) + ", ";
            if (toppings.size() > 0)
               message = message + 
		  (String) toppings.elementAt(toppings.size()-1);
            else 
               message = message + "none";

	    // Open file for append
	    if (DEBUG)
	       System.err.println("PizzaServerThread: setup output file");
	    fileout = new PrintWriter(
	       new FileWriter ("output/netorders.txt", true));
            fileout.write (message);
            fileout.write ("-------------------------------------------");
            fileout.flush();
            fileout.close();

            // Write response
	    if (DEBUG)
	       System.err.println("PizzaServerThread: write response");
            out.println (message);
	    out.println ("End");
            out.flush();
         }  // end try
	 catch (NullPointerException e) // Likely stream closed, so just return
	 {
	    cleanup();
	    return;
	 }
         catch (Exception e) // Print out error message for all others & exit
         { 
            System.err.println("PizzaServerThread: exception");
            e.printStackTrace();
	    System.exit (-1);
         }  // end catch
      }  // end while
   }  // end run

   void cleanup() 
   {
      if (DEBUG)
	 System.err.println("PizzaServerThread: cleaning up");
      try 
      {
         if (in != null) 
         {
            in.close();
            in = null;
         }  // end if
      }  // end try
      catch (Exception e) {} //Ignore errors.

      try
      {
         if (out != null) 
         {
            out.close();
            out = null;
         }  // end if
      }  // end try
      catch (Exception e) {} //Ignore errors.

      try
      {
         if (fileout != null) 
         {
            fileout.close();
            fileout = null;
         }  // end if
      }  // end try
      catch (Exception e) {} //Ignore errors.

      try
      {
         if (socket != null) 
         {
            socket.close();
            socket = null;
         }  // end if
      }  // end try
      catch (Exception e) {} //Ignore errors.
   }  // end cleanup

}  // end PizzaServerThread class
