
// RemoteHelloWorld.java
// Michele Loreti and the jSpace Developers, 2017
// Modified by Andrew Davison, ad@coe.psu.ac.th, May 2023

/* This version of HelloWorld uses a TCP space
  and three threads ("T1", "T2", "T3"). 

  If this is confusing, look at the non-distributed 
  concurrent version in ConcurrentHelloWorld.java.

  Usage:
    > compile.bat RemoteHelloWorld.java
    > run.bat RemoteHelloWorld

  Other versions: 
    * HelloWorld.java
    * ConcurrentHelloWorld.java
*/

import java.io.*;
import java.net.*;

import org.jspace.*;


public class RemoteHelloWorld
{
  private final static String GATE_URI = 
                        "tcp://localhost:9001/?keep";
           // used at repository creation time

  private final static String REMOTE_URI = 
                        "tcp://localhost:9001/aspace?keep";
           // used by the threads using the repository;
           // includes the name of the space in the repository


  public static void main(String[] argv)
  {
    SpaceRepository repository = new SpaceRepository();
    boolean res = repository.addGate(GATE_URI);

    // use one of these space classes; 
    // make sure the space name matches the one in REMOTE_URI
    repository.add("aspace", new VisSpace());
            // uses a default DELAY time of 2 secs (slow)
    // repository.add("aspace", new SequentialSpace());

    // two threads put data into the space
    Thread t1 = new Thread(() -> {
      try {
        RemoteSpace space = new RemoteSpace(REMOTE_URI);
        space.put("GREETING", "Hello");
      }
      catch (IOException | InterruptedException e) // two exception types
      {  System.out.println("T1 Error: " + e);  }
    }, "T1");  // VisSpace requires that threads be named

    Thread t2 = new Thread(() -> {
      try {
        RemoteSpace space = new RemoteSpace(REMOTE_URI);
        space.put("NAME", "World");
      }
      catch (IOException | InterruptedException e) 
      {  System.out.println("T2 Error: " + e);  }
    }, "T2");


    // one thread waits for two pieces of data in the space
    Thread t3 = new Thread(() -> {
      try {
        RemoteSpace space = new RemoteSpace(REMOTE_URI);
        Object[] greetingData =
              space.get( new ActualField("GREETING"), 
                         new FormalField(String.class));
        Object[] nameData =
              space.get( new ActualField("NAME"), 
                         new FormalField(String.class));

        // print both retrieved strings
        System.out.println(greetingData[1] + " " + nameData[1]);
      }
      catch (IOException | InterruptedException e) 
      {  System.out.println("T3 Error: " + e);  }
    }, "T3");

    t1.start();
    t2.start();
    t3.start();

    SpaceUtils.waitTerminated(t1, t2, t3);
        /* MUST be included or main() will terminate 
           before the remote threads have even started
        */
    repository.shutDown();
  } /* main */


}  // end of RemoteHelloWorld class
