// SimGet.java
// $Id: SimGet.java,v 1.1 1996/05/28 15:48:31 abaird Exp $
// (c) COPYRIGHT MIT and INRIA, 1996.
// Please first read the full copyright statement in file COPYRIGHT.html


package w3c.jigsaw.tests;

import java.io.* ;
import java.net.* ;
import java.util.Vector ;

class Waiter extends Thread {
    int  n ;
    int  c ;
    long times[] = null ;
    int  got[]   = null ;
    String url   = null ;

    synchronized void done (int tid, int sz, long time) {
	c++ ;
	times[tid] = time ;
	got[tid]   = sz ;
	if ( c == n )
	    notifyAll() ;
    }

    synchronized void waitForCompletion () {
	while ( n != c ) {
	    try { wait() ; } catch (InterruptedException e) {}
	}
    }

    public void run () {
	System.out.println ("waiter: waiting for " + n + " threads.") ;
	waitForCompletion() ;
	displayResults() ;
    }

    public void displayResults () {
	long min = Long.MAX_VALUE ;
	long max = 0 ;
	long sum = 0 ;
	int  sz  = got[0] ;
	for (int i = 0 ; i < times.length ; i++) {
	    if ( times[i] < min )
		min = times[i] ;
	    if ( times[i] > max )
		max = times[i] ;
	    sum += times[i] ;
	    if ( got[i] != sz ) 
		System.out.println ("Incoherent read "+got[i]+" vs "+sz) ;
	}
	System.out.println (url + " n=" + n + " size="+sz) ;
	System.out.println ("\tmin=" + min 
			    + " max=" + max 
			    + " avg="  + (sum/n)) ;
    }

    Waiter (String url, int n) {
	this.url   = url ;
	this.n     = n ;
	this.c     = 0 ;
	this.times = new long[n] ;
	this.got   = new int[n] ;
    }

}

class getter implements Runnable {
    Thread thread  = null ;
    URL    url     = null ;
    int    id      = - 1 ;
    Waiter waiter  = null ;
    
    public void run () {
	long tstart   = System.currentTimeMillis() ;
	int  got      = 0 ;
	byte buffer[] = new byte[8192] ;

	int i=-1 ; // testing
	URLConnection conn = null;
	try {
	    conn = url.openConnection() ;
	    InputStream in = null ;
	    in   = conn.getInputStream() ;
	    for (i = 0 ; (i = in.read(buffer)) > 0 ; got += i ) 
		;
	    in.close () ;
	} catch (Exception e) {
	    System.out.println("Exception: "+e) ;
	    e.printStackTrace() ;
	    System.out.println ("GET failed ! got="+got+"/"+i) ;
	}
	long tend = System.currentTimeMillis() ;
	waiter.done (id, got, tend-tstart) ;
    }
    getter (URL url, int id, Waiter waiter) {
	this.url    = url ;
	this.id     = id ;
	this.waiter = waiter ;
	this.thread = new Thread(this) ;
    }
}

/**
 * Server stresser: simultaneous GETs test.
 * This tests runs a number of simultaneous GET request to some target URL,
 * and prints out the mean, max and min times it took to run all the
 * requests.
 * <p><b>This test results should be taken with care</b>: they depend on a 
 * number of things, and usually run slower then C-written tests. They are
 * included in Jigsaw release for testing only (not for real benchmarking,
 * altough you are free to doi whatever you want with the numbers you get).
 */

public class SimGet {
    long times[] = null ;
    
    public static void usage() {
	System.out.println("SimGet -n <count> -url <url>") ;
	System.out.println("Get URL, COUNT times in parallel.");
	System.exit (1) ;
    }

    public static void main (String args[]) {
	int    n   = 1 ;
	String url = null ;
	if ( args.length < 2 ) {
	    String fake[] = { "-n", "5", "-url", "http://www.w3.org" } ;
	    args = fake ;
	}
	for (int i=0 ; i < args.length ; i++) {
	    if ( args[i].equals ("-url") ) {
		url = args[++i] ;
	    } else if ( args[i].equals("-n") ) {
		n   = Integer.parseInt (args[++i]) ;
	    } else {
		usage() ;
	    }
	}
	URL u = null ;
	try {
		u = new URL (url) ;
	} catch (MalformedURLException e) {
		System.out.println ("malformed URL.") ;
		System.exit (0) ;
	}
	Vector getters = new Vector(n) ;
	// Create all getters
	Waiter waiter = new Waiter (url, n) ;
	waiter.start() ;
	for (int i = 0 ; i < n ; i++) {
	    getter g = new getter(u, i, waiter) ;
	    getters.addElement (g) ;
	}
	// Run them all in paralle
	int vsize = getters.size() ;
	while ( --vsize >=0 ) {
	    getter g = (getter) getters.elementAt(vsize) ;
	    g.thread.start() ;
	}
	// Display results:
    }
    
}
