package org.jboss.cache.pojo;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.cache.config.Configuration.CacheMode;
import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
import org.jboss.cache.pojo.annotation.Replicable;
import org.testng.AssertJUnit;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

/**
 * Verifies that objects can be constructed without a public zero-arg constructor.
 *
 * @author Jason T. Greene
 */
@Test(groups = {"functional"})
public class NoZeroArgConstructorTest
{
   Log log = LogFactory.getLog(NoZeroArgConstructorTest.class);
   PojoCache cache, cache1;

   @BeforeClass(alwaysRun = true)
   protected void setUp() throws Exception
   {
      log.info("setUp() ....");
      boolean toStart = false;
      cache = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), toStart);
      cache.start();
      cache1 = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), toStart);
      cache1.start();
   }

   @AfterClass(alwaysRun = true)
   protected void tearDown() throws Exception
   {
      cache.stop();
      cache1.stop();
   }

   @Replicable
   public static class PrivateConstructor
   {
      private int x;
      private PrivateConstructor()
      {
      }

      public void setX(int x)
      {
         this.x = x;
      }

      public int getX()
      {
         return x;
      }
   }

   @Replicable
   public static class TwoArgConstructor
   {
      private int x;
      public TwoArgConstructor(double one, int two)
      {
      }

      public void setX(int x)
      {
         this.x = x;
      }

      public int getX()
      {
         return x;
      }
   }

   public void testPrivateConstructor()
   {
      PrivateConstructor priv = new PrivateConstructor();
      priv.setX(5);
      cache.attach("/foo/private", priv);
      PrivateConstructor priv2 = (PrivateConstructor) cache1.find("/foo/private");
      AssertJUnit.assertNotNull("Object not found", priv2);
      AssertJUnit.assertEquals(priv.getX(),  priv2.getX());
   }

   public void testTwoArgConstructor()
   {
      TwoArgConstructor cons = new TwoArgConstructor(1.0, 1);
      cons.setX(5);
      cache.attach("/foo/twoarg", cons);
      TwoArgConstructor cons2 = (TwoArgConstructor) cache1.find("/foo/twoarg");
      AssertJUnit.assertNotNull("Object not found", cons2);
      AssertJUnit.assertEquals(cons.getX(),  cons2.getX());
   }

}