/*
 * 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.Gadget;
import org.jboss.cache.aop.test.Resource;
import org.jboss.cache.aop.test.SpecialAddress;

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

/**
 * Test for JDK50 specific annotation.
 *
 * @author Ben Wang
 */
public class ReplicatedAnnotationAopTest extends TestCase
{
   Log log_= LogFactory.getLog(ReplicatedAnnotationAopTest.class);
   PojoCache cache_;
   PojoCache cache1_;

   public ReplicatedAnnotationAopTest(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 testTransientAnnotation() throws Exception
   {
      log_.info("testTransientAnnotation() ....");
      Gadget ga = new Gadget();
      ga.setName("Printer");
      Resource res = new Resource();
      res.setName("Inet");
      res.setConnection("Eth0");
      ga.setResource(res);

      cache_.putObject("/gadget", ga);
      Object obj = cache_.getObject("/gadget");
      assertEquals(ga, obj);

      Gadget ga1 = (Gadget)cache1_.getObject("/gadget");
      assertEquals("Name is ", ga.getName(), ga1.getName());

      assertNotNull("Resource should not be null on cache1 ", ga.getResource());
      assertNull("Resource should be null", ga1.getResource());
   }

   public void testSeriazableAnnotation() throws Exception
   {
      log_.info("testSerializableAnnotation() ....");
      Gadget ga = new Gadget();
      ga.setName("Printer");
      SpecialAddress addr = new SpecialAddress();
      addr.setAddr("10.1.2.2");
      ga.setAddr(addr);

      cache_.putObject("/gadget", ga);
      Object obj = cache_.getObject("/gadget");
      assertEquals(ga, obj);

      Gadget ga1 = (Gadget)cache1_.getObject("/gadget");
      assertEquals("Name is ", ga.getName(), ga1.getName());

      SpecialAddress addr1 = (SpecialAddress)ga1.getAddr();
      addr1.setAddr("5152967326");

      assertNotSame("Special address should not be updated: ", addr1.getAddr(), addr.getAddr());

      ga1.setAddr(addr1);
      assertEquals("Special address should be the same", ga.getAddr().getAddr(), ga1.getAddr().getAddr());

   }

   public void testSeriazableAnnotationWithRelationship() throws Exception
   {
      log_.info("testSerializableAnnotationWithRelationship() ....");
      Gadget ga = new Gadget();
      ga.setName("Printer");
      SpecialAddress addr = new SpecialAddress();
      addr.setAddr("10.1.2.2");
      ga.setAddr(addr);

      cache_.putObject("/gadget1", ga);
      Object obj = cache_.getObject("/gadget1");
      assertEquals(ga, obj);

      Gadget ga2 = new Gadget();
      ga2.setName("Fax");
      ga2.setAddr(addr);
      cache_.putObject("/gadget2", ga2);

      ga = (Gadget)cache1_.getObject("/gadget1");
      ga2 = (Gadget)cache1_.getObject("/gadget2");
      assertTrue("Sepcial address should be the same ", ga.getAddr() == ga2.getAddr());
   }

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


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

}
