/*

 * Date: 04/04/04

 * 

 * Server.java - a simple socket server.

 * Daria Antonova + some code from John Neffenger

 */



import java.io.*;

import java.net.*;



/**

 * <p>This class accepts socket connections on the specified port and replies

 * to messages sent to it by clients.

 */



public class TestServer implements Runnable {

    private static final String USAGE = "Usage: Server [-p port] [-v]";

    private static int TOTAL = 0;

    private static final int MAX = 100;

    

    private static int     port    = 6070;

    private static boolean verbose = false;



    

    // data structures for small database

    private static String[] names = new String[MAX]; // all student logins

    private static double[] halves = new double[MAX]; // all numbers

    private static int[][] scores = new int[MAX][MAX]; // all scores



    private Socket           socket;

    private DataInputStream  input;

    private PrintStream output;

    

    /**

     * Creates a connection from a socket.

     * @exception java.io.IOException when an error occurs creating the

     *            connection.

     */



    private TestServer(Socket socket) throws IOException {

        this.socket = socket;

        this.input  = new DataInputStream(socket.getInputStream());

        this.output = new PrintStream(socket.getOutputStream());

    }



    /**

     * The body of the server test.

     */



    public void run() {

        try {

            System.out.println("Echoing messages from client "

            		+ socket.getRemoteSocketAddress());

            String line = "start";

            String[] msg = new String[4];

            String reply = "empty";

            int temp; // exit with probability

            

            // echo data back to client while server receives data

            line = input.readLine();

            while(line != null && line.compareTo("exit") != 0 

            		&& reply.compareTo("exit") != 0) {

          

            	System.out.println("server got: " + line);

            	msg = line.split(":",4); 

            	reply = "reply:error";

            	if(msg[0].compareTo("login") == 0) {

            		reply = "replylogin:failed";

            		if(TOTAL < MAX) {

            			names[TOTAL] = new String(msg[1]);

            			reply = new String("replylogin:"+TOTAL);

            			TOTAL++;

            		}

            	}

            	if(msg[0].compareTo("request") == 0) {

            		reply = "replyrequest:empty";

            		for(int i=0; i<TOTAL; i++){

            			if(names[i].compareTo(msg[1]) == 0)

            				reply = "replyrequest:"+names[i]+":"+halves[i];

            		}

            	}

            	if(msg[0].compareTo("list") == 0) {

            		temp = (int)((Math.random()*100));

            		reply = "reply:emptylist";

            		if(TOTAL > 0 && temp > 30)

            			reply = "reply:"+names[(int)((Math.random()*100)%TOTAL)];

            		else { reply = "exit";}

            	}

            	if(msg[0].compareTo("guess") == 0) {

            		reply = "replyguess:incorrect";

            		for(int i=0; i<TOTAL; i++) {

            			System.out.println(msg[1]+" "+msg[2]);

            			if(names[i].compareTo(msg[2]) == 0

            					&& Double.compare(halves[i], Double.parseDouble(msg[3])) == 0) {

            				reply = "replyguess:correct";

            				if(scores[Integer.parseInt(msg[1])][i] == 0) {

            					scores[Integer.parseInt(msg[1])][Integer.parseInt(msg[1])]++;

            					scores[i][i]++;

            				}

            				scores[Integer.parseInt(msg[1])][i] = 1;

            				scores[i][Integer.parseInt(msg[1])] = 1;

            			}

            		}

            	}        

            	output.println(reply);

            	System.out.println("server sent: " + reply);

            	System.out.println("___________________________________");

            	for(int i=0; i<TOTAL; i++) {

            		System.out.println(names[i]+" "+scores[i][i]+" "+halves[i]);

            	}

            	System.out.println("___________________________________");

            	line = input.readLine();

            }

        }

        catch (EOFException e) {

            System.err.println("Connection closed by client.");

        }

        catch (IOException e) {

            System.err.println("Error in server: " + e);

        }

        finally {

            try {

                input.close();

                output.close();

                socket.close();

            }

            catch (IOException e) {}

        }

    }



    /**

     * Reads the command arguments and sets the static option variables.

     * @param args the command line arguments.

     * @exception java.lang.Exception when an error occurs parsing the options.

     */



    private static void setOptions(String[] args) throws Exception {

        int index = 0;

        while (index < args.length) {

            if (args[index].equals("-p")) {

                if (++index == args.length)

                    throw new Exception("Missing port number.");

                try {

                    port = Integer.parseInt(args[index]);

                }

                catch (NumberFormatException e) {

                    throw new Exception("Invalid port number: " + e);

                }

            }

            else if (args[index].equals("-v"))

                verbose = true;

            else

                throw new Exception("Unrecognized option: " + args[index]);

            index++;

        }

    }



    /**

     * Reads the command arguments and starts the test.

     * @param args the command line arguments.

     * @exception java.io.IOException when an error occurs creating the

     *            connection to the client.

     */



    public static void main(String args[]) throws IOException {

        for(int i=0; i<MAX; i++) {

        	halves[i] = Math.random();

        	for(int j=0; j<MAX; j++)

        		scores[i][j] = 0;	

        }

    	try {

            setOptions(args);

        }

        catch (Exception e) {

            System.err.println(e.getMessage());

            System.err.println(USAGE);

            System.exit(1);

        }

        System.out.println("Creating server socket on server " 

			+ InetAddress.getLocalHost() + " port " + port + " ...");

        ServerSocket serverSocket = new ServerSocket(port);

        System.out.println("Accepting connections ...");

        while (true) {

            Socket socket = serverSocket.accept();

            InetAddress address = socket.getInetAddress();

            System.out.println("Connection is from " +

                address.getHostAddress() + " (" + address.getHostName() + ").");

            TestServer server = new TestServer(socket);

            Thread thread = new Thread(server);

            thread.start();

        }

    }

}