
// RoomReader.java
// Andrew Davison, ad@coe.psu.ac.th, May 2023

/* Repeatedly read *all* the tuples in the space, but only
   print those added since the start of this thread and
   only those which have not been printed before.

   Repeatedly reading everything every 500 ms is an expensive
   way to monitor the space for changes.

  Usage:
    > compile.bat RoomReader.java

    Part of the application made up of:
       * ChatServer.java
       * ChatClient.java
       * RoomReader.java
            -- this class is not in the original examples
*/

import java.io.*;
import java.util.*;
import java.text.*;

import org.jspace.*;


public class RoomReader extends Thread
{
  private DateFormat sdf = new SimpleDateFormat("HH:mm:ss");

  private Space chatSpace;
  private String roomID;

  private LinkedList<Object[]> seenMsgs;
        // copy of the messages that have already been seen
  private boolean isRunning = true;
  private Date startTime;


  public RoomReader(String roomID, Space space)
  {
    super("RoomReader");
    this.roomID = roomID;
    chatSpace = space;

    seenMsgs = new LinkedList<>();

    startTime = Calendar.getInstance().getTime();
    // System.out.println("Start time: " + startTime);
  } // end of RoomReader()



  public void stopReading()
  {  isRunning = false;  }


  public void run()
  {
    try { /* Keep re-reading every message sent to the 
             chat space; print only the new stuff */
      while (isRunning) {
        List<Object[]> msgs = chatSpace.queryAll( 
                     new FormalField(String.class),  // userID
                     new FormalField(String.class),  // message
                     new FormalField(Date.class));   // timestamp
        for (Object[] msg : msgs) {
          Date timestamp = (Date)msg[2];
          // System.out.println("timestamp: " + timestamp);
          if ((timestamp.compareTo(startTime) > 0) &&  
                                // after start time of this reader
             (!alreadySeen(msg))) {   // and not printed before
            System.out.println("Room " + roomID + " | " + 
                  msg[0] + " : " + msg[1] + 
                  " (" + sdf.format(msg[2]) + ")"); 
            seenMsgs.add(msg);   // this message has been seen
          }
        }
        SpaceUtils.pause(500);
      }
    }
    catch (InterruptedException e) 
    {  System.out.println(e); }
  } /* run */


  private boolean alreadySeen(Object[] msg)
  {
    for (Object[] chatMsg : seenMsgs) {
      if (Arrays.equals(msg, chatMsg))
        return true;
    }
    return false;
  }

}  // end of RoomReader class
