
// ChatClient.java
// Andrew Davison, ad@coe.psu.ac.th, May 2023

/* This code uses the user's ID and the ID of the chatroom
   a user want to join to post a ("enter", <user ID>, <room ID>) 
   tuple in the chat server's lobby space.

   The server responds with a tuple:
      ("roomURI", <user ID>, <room ID>, roomURI)
   and this code uses the roomURI to access the remote 
   chatroom space.

   A user chats inside a chatroom by typing a message, which
   is posted to the space as a tuple of the form:
      (userID, message, timestamp)
   The ID and timestamp are added automatically.

   This code prints chat messages by starting a RoomReader thread
   which prints out all the new messages added to the chatroom
   space since the thread was created.

   A user leaves a chatroom by sending a "quit" message.

   A user can get a list of all the users by typing "who", but
   the list also includes any users who have left the room.

   Explained in sections 3.5 and 3.6 at:
    https://github.com/pSpaces/Programming-with-Spaces/blob/master/tutorial-distributed-programming.md

  Usage:
    > compile.bat ChatClient.java
    > run.bat ChatClient <userID> <roomID>
    e.g.
    > run ChatClient andrew coe
       -- start in a separate window after starting ChatServer
       -- start at least two ChatClients

    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 ChatClient
{
  private final static String REMOTE_URI = 
                  "tcp://127.0.0.1:9001/lobby?keep";

  private static RoomReader reader;


  public static void main(String[] args)
  {
    if (args.length != 2) {
      System.out.println("Usage: run ChatClient <userID> <chatroomID>");
      return;
    }
    String userID = args[0];
    String roomID = args[1];

    try {
      System.out.println("Connecting to lobby " + REMOTE_URI + "...");
      RemoteSpace lobby = new RemoteSpace(REMOTE_URI);

      System.out.println(userID + " requesting to join chatroom " + roomID);
      lobby.put("enter", userID, roomID);
      Object[] response = lobby.get( 
                        new ActualField("roomURI"),
                        new ActualField(userID),
                        new ActualField(roomID),
                        new FormalField(String.class));
      String roomURI = (String) response[3];

      System.out.println("Ok. Connecting to chatroom " + roomURI);
      RemoteSpace chatSpace = new RemoteSpace(roomURI);

      reader = new RoomReader(roomID, chatSpace);
      reader.start();

      System.out.println("Start chatting... (exit with \"quit\")");
      Date startTime = Calendar.getInstance().getTime();
      chatSpace.put(userID, "has joined this chat", startTime);
      Console console = System.console();
      while(true) {
        String message = console.readLine();
        Date timestamp = Calendar.getInstance().getTime();
        if (message.equals("quit")) {
          chatSpace.put(userID, "has left", timestamp);
          reader.stopReading();
          break;
        }
        else if (message.equals("who"))
          who(chatSpace);
        else 
          chatSpace.put(userID, message, timestamp);
      }
      System.out.println("Closing client");
      System.exit(0);
    }
    catch (Exception e) 
    {  System.out.println(e);  }
  } /* main */



  private static void who(RemoteSpace chatSpace)
  // list all the users who have used this chatroom
  {
    try {
      List<Object[]> msgs = chatSpace.queryAll( 
                    new FormalField(String.class),  // userID
                    new FormalField(String.class),  // message
                    new FormalField(Date.class));   // timestamp
      ArrayList<String> users = new ArrayList<>();
      for (Object[] msg : msgs) {
        String userID = (String)msg[0];
        if (!users.contains(userID))
          users.add(userID);
      }
      System.out.println("Users: " +  users);
    }
    catch (InterruptedException e) 
    {  System.out.println(e); }
  }  // end of who()


}  // end of ChatClient class
