/*
 * Script ?? Exercise 
 *
 * implement RMI example
 *
 */

//import java.math.*;
import java.net.*;
import java.rmi.*;
import java.rmi.server.*;

class ex21l implements Runnable {
 
  int id, m, k;
  private int primes[] = null;
  SmallPrimeInf sp;
  String host = "localhost"; 

  public ex21l(int li, String h) {
    id = li; 
    if (h != "") { host = h; }

    // lookup
    try { sp = (SmallPrimeInf) Naming.lookup("rmi://" 
                               + host + "/SmallPrime"); }
    catch (RemoteException re) {
      System.err.println("RemoteException in ex21l " + re);
      System.exit(-1);
      } 
    catch (NotBoundException nb) {
      System.err.println("NotBoundException " + nb);
      System.exit(-1);
      } 
    catch (MalformedURLException u) {
      System.err.println("MalformedURLException in ex21l " + u);
      System.exit(-1);
      } 
    catch (ClassCastException c) {
      System.err.println("ClassCastException in ex21l " + c);
      System.exit(-1);
      } 
    System.out.println("method found in " + id);
  }


  public void run() {

    int w, t = 0; 

    while (true) {
      synchronized (ex21c.wmux) { ex21c.todo -= 1; 
                                  w = ex21c.todo; }
      if ( w <= 0 ) break; 
      t++;

      Integer ns = (Integer)ex21c.work.get(); 
      Integer ks = (Integer)ex21c.work.get(); 
      m = ns.intValue(); k = ks.intValue();

      try { primes = sp.genSmallPrimes(m,k); 
      }
      catch (RemoteException re) {
        System.err.println("RemoteException in ex21l " + re);
        System.exit(-1);
      } 

      System.out.println("id = " + id 
          + ", primes = " + primes.length
          + " from " + m + " to " + (m+k));
      synchronized (ex21c.mux) { ex21c.num += primes.length; }
    }

    System.out.println("id = " + id + ", done = " + t );
  }
}  

public class ex21c {

  /*parameters */
  public static final int t = 5, w = 1000;

  public static String host = ""; 
  public static String trumpf = "trumpf-"; 
  public static String rum = ".rz.uni-mannheim.de"; 

  static int n = 3, k = 10*w;

  static int num = 0;
  static Object mux = null;

  public static int todo = 0;
  static Object wmux = null;
  public static Queue work = null;
 
  static void usage() {
       System.out.println("usage: java ex21c host begin end");
  }

  public static void main(String[] args) throws InterruptedException {

    if (args.length < 1 || args.length >3) { 
       usage();
    } 
    if (args.length >= 1) { 
       host = args[0]; 
    } 
    if (args.length >= 2) { 
       try { n = Integer.parseInt(args[1]); } 
       catch (NumberFormatException e) { 
           System.err.println("NumberFormatException args[1] = " + args[1]);
           usage();
       } 
    } 
    if (args.length >= 3) { 
       try { k = Integer.parseInt(args[2]); } 
       catch (NumberFormatException e) { 
           System.err.println("NumberFormatException args[2] = " + args[2]);
           usage();
       } 
    } 
    mux = new Object();

    todo = w;
    work = new Queue(2*w+10);
    wmux = new Object();
  
    /* divide work */
    int kp = k/w;
    int np = n;
    for (np = n; np < n+k; np+=kp) {
        Integer ns = new Integer(np); 
        Integer ks = new Integer(kp); 
        work.put(ns); work.put(ks); 
    }
    System.out.println("Calling methods on host " + host);

    /* con statement */
    Thread pt[] = new Thread[t]; 
    for (int j = 0; j < t; j++) {
         pt[j] = new Thread( new ex21l(j,host) );
         pt[j].start();
       }
    System.out.println("Threads started");

    for (int j = 0; j<t; j++) { pt[j].join(); }
    System.out.println("Threads done");
    
    System.out.println("total primes = " + num);

    System.out.println("termination");
  }

}




