/*******************************************************************************
 * Bunshin : DHT Replication & Caching
 * Copyright (C) 2004-2005 Ruben Mondejar
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 ******************************************************************************/

package bunshin.test;

import junit.framework.*;
import bunshin.storage.*;
import bunshin.*;

import java.util.*;
import rice.p2p.commonapi.*;
import bunshin.util.*;


/**
 * Bunshin's main testcase
 *
 * @author Ruben Mondejar  <ruben.mondejar@estudiants.urv.es>
 */
public class SimpleTest extends TestCase {

  protected static BunshinSearch[] bunshin;
  protected final static int num = 5;
  protected static Id global_id = null;

  public SimpleTest(String name) {
	super(name);
  }

  protected void setUp() {
		
    try {
  	  bunshin = new BunshinSearch[num];
  	  for (int i=0; i<num; i++) {  	  	
  	  	bunshin[i] = new BunshinSearch("auto",5009);
  	  	Thread.sleep(1000);
  	    bunshin[i].init("BunshinTest", new MemStorage(),3,8,false,true);  	    
  	  }		  
	  
	} catch (Exception e1) {
	  e1.printStackTrace();	
	}	
  }
  
  public static void finishTest() {
	  for (int i=0; i<num; i++) {
	  	bunshin[i].leave(); 	      	    
  	  }		  
  	
  }


  public static Test suite() {
    return new TestSuite(SimpleTest.class);
  }


  public void testStore() throws Exception {    
	
    String id = "time";
    long time = System.currentTimeMillis();
                  
    Id key = bunshin[0].storeObject(id,new Long(time));    
      
    Thread.currentThread().sleep(5000);
    
    long time2 = System.currentTimeMillis();
                  
    bunshin[0].storeObject(id,new Long(time2));    
      
    Thread.currentThread().sleep(5000);
    
    Long tr = (Long) bunshin[num-1].retrieveObject(key);    
     		
	assertEquals(time2,tr.longValue());
    
	finishTest();
  }
 

  
  public void testStoreDuplicate() throws Exception {    
	
    String id = "time";
    long time = System.currentTimeMillis();
                  
    Id key = bunshin[0].storeObject(id,new Long(time));    
      
    Thread.currentThread().sleep(5000);
    
    long time2 = System.currentTimeMillis();
                  
    bunshin[1].storeObject(id,new Long(time2));    
      
    Thread.currentThread().sleep(5000);
    
    Long tr = (Long) bunshin[num-1].retrieveObject(key);    
     		
	assertEquals(time2,tr.longValue());
	
	finishTest();
  }
  
   public void testStoreCVS() throws Exception {    
	
    String id = "time";
    long time = System.currentTimeMillis();    
    Values v1 = new Values();                  
    v1.put("Object",new Long(time));              
    
    Id key = bunshin[0].storeObject(id,v1);    
      
    Thread.currentThread().sleep(5000);
    
    long time2 = System.currentTimeMillis();
    Values v2 = new Values();                  
    v2.put("Object",new Long(time2));        
                  
    bunshin[1].storeObject(id,v2);    
      
    Thread.currentThread().sleep(5001);
    
    long time3 = System.currentTimeMillis();
    Values v3 = new Values();                  
    v3.put("Object",new Long(time3)); 
    v3.put("CVS",new Integer(0));      
                  
    bunshin[2].storeObject(id,v3);    
      
    Thread.currentThread().sleep(5001);
    
    Long tr = (Long) bunshin[num-1].retrieveObject(key);    
     		
	assertEquals(time2,tr.longValue());
	
	finishTest();
  }
  
	  
   public void testMultiContext() throws Exception {    
	
		String key = "time";
	    Id id = Utilities.generateHash(key);

		long time = System.currentTimeMillis();
                  
		bunshin[0].storeObject("context1",id,new Long(time));    

      
		Thread.currentThread().sleep(5000);
    
		long time2 = System.currentTimeMillis();
                  
		bunshin[1].storeObject("context2",id,new Long(time2));    
      
		Thread.currentThread().sleep(5000);
    
		Long tr = (Long) bunshin[num-1].retrieveObject("context1",id);    
     		
		assertEquals(time,tr.longValue());

	    tr = (Long) bunshin[num-1].retrieveObject("context2",id);    
     		
	    assertEquals(time2,tr.longValue());
	
		finishTest();
	}
  
	
  public void testLinkListener() throws Exception {
  	
  	//key unique
  	String google_url = "http://www.google.com";
    //generate Id
  	Id google_id = Utilities.generateHash(google_url);
  	
  	Hashtable google_info = new Hashtable();
  	google_info.put("url",google_url);
  	google_info.put("date",new Date());
  	
  	//insert key,value
  	bunshin[1].storeObject(google_id,google_info);
  	Thread.currentThread().sleep(1000);
  	
  	String etse_url = "http://www.etse.urv.es";
    //generate Id
  	Id etse_id = Utilities.generateHash(etse_url);
  	
  	Hashtable etse_info = new Hashtable();
  	etse_info.put("url",etse_url);
  	etse_info.put("date",new Date());
  	
    //insert key,value
  	bunshin[3].storeObject(etse_id,etse_info);  	  	
  	Thread.currentThread().sleep(1000);
  	
  	global_id = null;
  	//add listener 
  	bunshin[0].setLinkListener(etse_id,new RemoteListener(){
  	  public void eventArrived(Object value, boolean added) {  
	  	
  	  	if (value instanceof Collection) {
  	  	
  	  	  Iterator it = ((Collection) value).iterator();  	     	
  	  	
  	      global_id = (Id) it.next();
  	    
  	    }
  	    else if (value instanceof Id) {
  	      	      	    
  	      global_id = (Id) value;
  	    
  	    }
  	    System.out.println("\n New incoming link to http://www.etse.urv.es -> link_id : "+global_id+" \n");  	    
	  }
    });
    
  	Thread.currentThread().sleep(2000);
  	
  	//add link
  	Vector google_links = new Vector();
  	google_links.add(etse_id);
  	bunshin[2].addLinks(google_id,google_links);
  	Thread.currentThread().sleep(1000);
  	
  	assertEquals(google_id,global_id);
	
	finishTest();
  		
  }
  
  
  
    	
  	
}