// RegServer.java: The server for the appelt repsonsible for
// writing on the server side
package Chapter16;

import java.io.*;
import java.net.*;
import Chapter15.Student;

public class RegServer 
{
  // Main method
  public static void main(String[] args)
  {
    // A random access file
    RandomAccessFile raf = null;

    // Open the local file on the server side
    try
    {
      // Open the file if the file exists, create a new file
      // if the file does not exist
      raf = new RandomAccessFile("student.dat", "rw");
    }
    catch(IOException ex)
    {
      System.out.println("Error: " + ex);
      System.exit(0);
    }

    // Establish server socket
    try
    {
      // Create a server socket
      ServerSocket serverSocket = new ServerSocket(8000);

      // Count the number of threads started
      int count = 1;

      while (true)
      {
        // Connect to a client
        Socket socket = serverSocket.accept();

        // Start a new thread to register a client
        new RegistrationThread(raf, socket, count++).start();
      }
    }
    catch (IOException ex)
    {
      System.err.println(ex);
    }
  }
}

// Define a thread to process the client registration
class RegistrationThread extends Thread
{
  // The socket to serve a client
  private Socket socket;

  // The file to store the records
  static RandomAccessFile raf = null;

  private int num; // The thread number

  // Buffered reader to get input from the client
  private BufferedReader in;

  // Create a registration thread
  public RegistrationThread(RandomAccessFile raf,
    Socket socket, int num)
  {
    this.raf = raf;
    this.socket = socket;
    this.num = num;

    System.out.println("Thread " + num + " running");

    // Create an input stream to receive data from a client
    try
    {
      in = new BufferedReader
        (new InputStreamReader(socket.getInputStream()));
    }
    catch(IOException ex)
    {
      System.out.println("Error: " + ex);
    }
  }

  public void run()
  {
    String name;
    String street;
    String city;
    String state;
    String zip;

    try
    {
      // Receive data from the client
      name = new String(in.readLine());
      street = new String(in.readLine());
      city = new String(in.readLine());
      state = new String(in.readLine());
      zip = new String(in.readLine());

      // Display data received
      System.out.println(
        "The following data received from the client");
      System.out.println("name: " + name);
      System.out.println("street: " + street);
      System.out.println("city: " + city);
      System.out.println("state: " + state);
      System.out.println("zip: " + zip);

      // Create a student instance
      Student student = new Student(name, street, city, state, zip);

      writeToFile(student);
    }
    catch (IOException ex)
    {
      System.out.println(ex);
    }
  }

  private synchronized static void writeToFile(Student student)
  {
    try
    {
    // Append it to "student.dat"
    raf.seek(raf.length());
    student.writeStudent(raf);
    }
    catch (IOException ex)
    {
      System.err.println(ex);
    }
  }
}
