/*
 * JBoss, Home of Professional Open Source
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

package org.jboss.cache.aop;

import junit.framework.TestCase;
import junit.framework.Test;
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.aop.test.Student;
import org.jboss.cache.aop.test.CacheObject;
import org.jboss.cache.aop.test.NonSerializableObject;

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

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

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

   public ReplicatedSerializableAopTest(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 testSeriazableSubObject() throws Exception
   {
      log_.info("testSerializableSubObject() ....");

      Student ben = new Student();
      ben.setName("Ben");
      ben.setYear("9th grade");
      CacheObject co1 = new CacheObject("1");
      ben.setCO1(co1);
      CacheObject co2 = new CacheObject("2");
      ben.setCO2(co2);

      cache_.putObject("/test", ben);

      Student be = (Student)cache1_.getObject("/test");
      assertNotNull("CacheObject should not be null", be.getCO1());
      assertNotNull("CacheObject should not be null", be.getCO2());
      assertEquals("1", be.getCO1().getId());
      assertEquals("2", be.getCO2().getId());
   }

   /**
    * We don;t currently support Serializable with relationship now.
    * @throws Exception
    */
   public void XtestSeriazableSubObjectRelation() throws Exception
   {
      log_.info("testSerializableSubObjectRelation() ....");

      Student ben = new Student();
      ben.setName("Ben");
      ben.setYear("9th grade");
      CacheObject co1 = new CacheObject("1");
      ben.setCO1(co1);

      Student elynne = new Student();
      elynne.setName("Elynne");
      elynne.setYear("9th grade");
      // Same co object
      elynne.setCO1(co1);

      cache_.putObject("/ben", ben);
      cache_.putObject("/elynne", elynne);

      Student be = (Student)cache1_.getObject("/ben");
      Student el = (Student)cache1_.getObject("/elynne");
      assertNotNull("CacheObject should not be null", be.getCO1());
      assertNotNull("CacheObject should not be null", el.getCO1());
      assertEquals("Both co object should be the same", be.getCO1().getId(), el.getCO1().getId());
      assertTrue("Both co should be the same reference", be.getCO1() == el.getCO1());
   }

   public void testPlainSeriazable() throws Exception
   {
      log_.info("testPlainSerializable() ....");
      // First the flag is set to false
      CacheObject co = new CacheObject("1");
      cache_.putObject("/test", co);
      CacheObject co1 = (CacheObject)cache1_.getObject("/test");
      assertNotNull("co on remote cache should not be null", co1);
      assertEquals("co should be the same", co.getId(), co1.getId());

   }

   public void testNonSeriazable1() throws Exception
   {
      log_.info("testNonSerializable1() ....");
      // First the flag is set to false
      NonSerializableObject nso = new NonSerializableObject();
      nso.setId("2");
      try {
         cache_.putObject("/test", nso);
         fail("should fail becuase vo is not Serializable");
      }
      catch (RuntimeException e) {
      }

      // Then we set the flag
      cache_.setMarshallNonSerializable(true);
      cache1_.setMarshallNonSerializable(true);
      cache_.putObject("/test", nso);
      NonSerializableObject nso1 = (NonSerializableObject)cache1_.getObject("/test");
      assertNotNull("nso on remote cache should not be null", nso1);
      assertEquals("VO should be the same", nso, nso1);

   }

   public void testNonSeriazable2() throws Exception
   {
      log_.info("testNonSerializable2() ....");
      // First the flag is set to false
      NonSerializableObject nso = new NonSerializableObject();
      nso.setId("2");

      // Then we set the flag
      cache_.setMarshallNonSerializable(true);
      cache1_.setMarshallNonSerializable(true);
      cache_.putObject("/test", nso);
      NonSerializableObject nso1 = (NonSerializableObject)cache1_.getObject("/test");
      assertNotNull("nso on remote cache should not be null", nso1);
      assertEquals("VO should be the same", nso, nso1);

      nso1 = new NonSerializableObject();
      nso1.setId("4");
      cache1_.putObject("/test", nso1);
      nso = (NonSerializableObject)cache_.getObject("/test");
      assertNotNull("nso on remote cache should not be null", nso);
      assertEquals("VO should be the same", nso, nso1);

   }

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


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

}
