package MV3500Cohort2024JulySeptember.homework2.Matiski;

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

/**
 * <p>
 * This utility class supports the {@link TcpExamples.TcpExample4DispatchServer} program,
 * handling all programming logic needed for a new socket connection
 * to run in a thread of its own. This is the server
 * portion as well, so we artificially invent what happens
 * if the server can't respond to a connection for several seconds.
 * </p>
 * <p>
 * Warning: do not run this class!  It is created and used automatically by {@link TcpExamples.TcpExample4DispatchServer} at run time.
 * </p>
 * 
 * @see TcpExample4Client
 * @see TcpExample4DispatchServer
 *
 * @see <a href="../../../src/TcpExamples/TcpExample4TerminalLog.txt" target="blank">TcpExample4TerminalLog.txt</a>
 * @see <a href="../../../src/TcpExamples/TcpExample4SequenceDiagram.png" target="blank">TcpExample4SequenceDiagram.png</a>
 * @see <a href="../../../src/TcpExamples/TcpExample4SequenceSketch.png" target="blank">TcpExample4SequenceSketch.png</a>
 * 
 * @author Don McGregor
 * @author Don Brutzman
 * @author MV3500 class
 */
public class Matiski2HandlerThread extends Thread
{
    /** The socket connection to a client */
    Socket socket;
    
    /** 
     * The thread constructor creates the socket from a ServerSocket, waiting for the client to connect,
     * and passes that socket when constructing the thread responsible for handling the connection.
     * 
     * @param socket The socket connection handled by this thread
     */
    Matiski2HandlerThread(Socket socket)
    {
        this.socket = socket;
    }
    /**
     * Program invocation and execution starts here - but is illegal and unwanted, so warn the unsuspecting user!
     * @param args command-line arguments
     */
    public static void main(String[] args)
    {
        System.out.println ("*** TcpExample4HandlerThread is not a standalone executable progam.");
        System.out.println ("*** Please run TcpExample4DispatchServer instead... now exiting.");
    }
    
    /** Handles one connection. We add an artificial slowness
     * to handling the connection with a sleep(). This means
     * the client won't see a server connection response for ten seconds (default).
     */
    // @overriding run() method in Java Thread class is deliberate
@Override 
public void run()
{
    try
    {
        System.out.println(Matiski2HandlerThread.class.getName() + " starting to handle a thread...");

        // Set up input and output streams for communication
        InputStream is = socket.getInputStream();
        Reader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);

        OutputStream os = socket.getOutputStream();
        PrintStream ps = new PrintStream(os);

        // Ask for password
        final String correctPassword = "Mark"; 
        ps.println("Enter password:"); 
        ps.flush();

        String clientPassword = br.readLine(); // Read the password sent by the client

        boolean isPasswordCorrect = correctPassword.equals(clientPassword);
        if (isPasswordCorrect) {
            ps.println("Password accepted. Processing your request...");
            ps.flush();

            final long TIMEOUT = 2000; // 2000 milliseconds = 2 seconds
            System.out.println(Matiski2HandlerThread.class.getName() + " pausing for TIMEOUT=" + TIMEOUT + "ms" + 
                               " to emulate computation and avoid server-side overload"); 
            Thread.sleep(TIMEOUT);

            // Continue with the original logic
            ps.println("This message was written by the server " + Matiski2HandlerThread.class.getName()); 
            ps.flush();
        } else {
            ps.println("Incorrect password. Connection will be terminated.");
            ps.flush();
        }

        // Inform the client that the connection will be closed
        if (isPasswordCorrect) {
            ps.println("Your request has been processed. The connection will now be closed.");
        } else {
            ps.println("Due to incorrect password, the connection will be closed.");
        }
        ps.flush();

        socket.close(); // Close the socket after handling the connection
        System.out.println(Matiski2HandlerThread.class.getName() + " finished handling a thread, now exit.");
    }
    catch(IOException | InterruptedException e) 
    {
        System.out.println("Problem with " + Matiski2HandlerThread.class.getName() + " networking:"); 
        System.out.println("Error: " + e);
        
        if (e instanceof java.net.BindException)
            System.out.println("*** Be sure to stop any other running instances of programs using this port!");
    }
}

}