package org.jboss.cache.aop;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.cache.PropertyConfigurator;
//import org.jboss.cache.data.Address;
//import org.jboss.cache.data.Course;
//import org.jboss.cache.data.RandomString;
//import org.jboss.cache.aop.PojoCache;
import org.jboss.cache.aop.test.Person;
import org.jboss.cache.aop.test.Student;
import org.jboss.cache.aop.test.CacheObject;
import org.jboss.cache.aop.test.Address;

import javax.naming.Context;
import java.util.Properties;


/**
 * New NewReplicatedAopTest that doesn't use TreeCacheAopTester.
 *
 * @author Ben Wang
 */

public class NewReplicatedAopTest extends TestCase
{
   Log log_=LogFactory.getLog(NewReplicatedAopTest.class);
   PojoCache cache_;
   PojoCache cache1_;

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

   protected void setUp() throws Exception
   {
      super.setUp();
      Properties prop = new Properties();
      prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.cache.transaction.DummyContextFactory");
      cache_ = new PojoCache();
      PropertyConfigurator config = new PropertyConfigurator(); // configure tree cache.
      config.configure(cache_, "META-INF/replSync-service.xml");

      cache1_ = new PojoCache();
      config.configure(cache1_, "META-INF/replSync-service.xml");
      cache_.start();
      cache1_.start();
   }

   protected void tearDown() throws Exception
   {
      super.tearDown();
      cache_.stop();
      cache1_.stop();
   }

   /*
   public void testObjectSizePut() throws Exception
   {
      org.jboss.cache.data.Student student = (org.jboss.cache.data.Student)constructObject();
      cache_.putObject("/joe", student);
   }


   static Object constructObject()
   {
      org.jboss.cache.data.Student joe = new org.jboss.cache.data.Student();
      joe.setName("Joe");

      Address add = new Address();
      add.setZip(94086);
      add.setCity("Sunnyvale)");
      add.setStreet("Albertson");
      joe.setAddress(add);

      String str;
      for(int i=0; i < 100; i++)
      {
         Course course = new Course();
         str = RandomString.randomstring(10,20);
         course.setInstructor(str);
         str = RandomString.randomstring(10,20);
         course.setTitle(str);
         str = RandomString.randomstring(10,20);
         course.setRoom(str);
         joe.addCourse(course);
      }

      return joe;
   }
   */
   public void testRemoteRemove() throws Exception
   {
      log_.info("testRemoteRemove() ....");
      Person test = new Person();
      test.setName("Ben");
      test.setAge(10);
      Address addr = new Address();
      addr.setCity("Taipei");
      addr.setZip(106);
      test.setAddress(addr);
      cache_.putObject("/a", test);
      Person result = (Person)cache_.getObject("/a");
      assertEquals(" ", test, result);

      Person remote = (Person)cache1_.getObject("/a");
      assertEquals("Age should be ", 10, remote.getAge());

      // Remote remove
      cache_.removeObject("/a");
      assertNull("Object should be null ", cache_.getObject("/a"));

      assertNull("Object should be null ", cache1_.getObject("/a"));
      // It is 0 since it will be un-initialized.
      assertEquals("Age should be ", 0, remote.getAge());
   }

   public void testSubClass() throws Exception
   {
      log_.info("testsubClass() ....");
      Student test = new Student();
      test.setName("Ben");
      test.setAge(10);
      Address addr = new Address();
      addr.setCity("Taipei");
      addr.setZip(106);
      test.setAddress(addr);
      cache_.putObject("/a", test);
      Student result = (Student)cache_.getObject("/a");
      assertEquals(" ", test, result);

      Student remote = (Student)cache1_.getObject("/a");
      System.out.println("Output on cache1: "+ result);
      System.out.println("Output on cache2: "+ remote);
      assertEquals("Age should be ", 10, remote.getAge());
   }

   public void testPutArray1() throws Exception
   {
      log_.info("testPutArray1() ....");
      long[] arr = new long[] {1, 2};
      cache_.putObject("array", arr);

      long[] a2 = (long[])cache1_.getObject("array");
      assertEquals("arr 0", 1, a2[0]);
   }

   public void testPutArray2() throws Exception
   {
      log_.info("testPutArray2() ....");
      Person p1 = new Person();
      p1.setName("Ben");
      p1.setAge(10);

      Person p2 = new Person();
      p2.setName("Joe");
      p2.setAge(20);
      Person[] arr = new Person[] {p1, p2};

      cache_.putObject("array", arr);

      Person[] a2 = (Person[])cache1_.getObject("array");
      assertEquals("arr 0", "Ben", a2[0].getName());
   }


   /**
    * JBCACHE-200.
    * @throws Exception
    */
   public void testStateTransfer() throws Exception
   {
      log_.info("testStateTransfer() ....");
      Person test = new Person();
      test.setName("Ben");
      test.setAge(10);
      cache_.putObject("/a", test);
      Person result = (Person)cache_.getObject("/a");
      assertEquals(" ", test, result);

      // restart cache1_
      cache1_.stop();
      cache1_.remove("/a");
      cache1_.start();
      // Start from scratch for initial state transfer
      Person remote = (Person)cache1_.getObject("/a");
      assertEquals("Age should be ", 10, remote.getAge());
   }

   public static Test suite() throws Exception
   {
      return new TestSuite(NewReplicatedAopTest.class);
   }


   public static void main(String[] args) throws Exception
   {
      junit.textui.TestRunner.run(suite());
   }

}

