package org.jboss.cache.optimistic;

import org.jboss.cache.CacheSPI;
import org.jboss.cache.Fqn;
import org.jboss.cache.NodeSPI;
import org.jboss.cache.util.TestingUtil;
import org.jboss.cache.config.Configuration;
import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNull;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import javax.transaction.TransactionManager;

/**
 * Tests removal of a node before the node is even created.
 */
@Test(groups = "functional")
public class RemoveBeforeCreateTest extends AbstractOptimisticTestCase
{
   CacheSPI<Object, Object>[] c = null;
   TransactionManager t;

   @BeforeMethod(alwaysRun = true)
   public void setUp() throws Exception
   {
      c = new CacheSPI[2];
      c[0] = createReplicatedCache(Configuration.CacheMode.REPL_ASYNC);
      c[1] = createReplicatedCache(Configuration.CacheMode.REPL_ASYNC);

      TestingUtil.blockUntilViewsReceived(c, 20000);

      t = c[0].getTransactionManager();
   }

   @AfterMethod(alwaysRun = true)
   public void tearDown()
   {
      if (c != null)
      {
         destroyCache(c[0]);
         destroyCache(c[1]);
         c = null;
      }
   }

   @SuppressWarnings("unchecked")
   public void testControl() throws Exception
   {
      t.begin();
      c[0].put("/control", "key", "value");
      t.commit();
      TestingUtil.sleepThread(200);

      assertEquals("value", c[0].get("/control", "key"));
      assertEquals("value", c[1].get("/control", "key"));

      DefaultDataVersion v1 = (DefaultDataVersion) ((NodeSPI) c[0].getNode("/control")).getVersion();
      assertEquals(1, v1.getRawVersion());

      DefaultDataVersion v2 = (DefaultDataVersion) ((NodeSPI) c[1].getNode("/control")).getVersion();
      assertEquals(1, v2.getRawVersion());


   }

   @SuppressWarnings("unchecked")
   public void testRemoveBeforePut() throws Exception
   {
      Fqn f = Fqn.fromString("/test");
      assertNull(c[0].getNode(f));
      assertNull(c[1].getNode(f));

      t.begin();
      c[0].removeNode(f);

      // should NOT barf!!!
      t.commit();
      TestingUtil.sleepThread(200);

      assertNull(c[0].getNode(f));
      assertNull(c[1].getNode(f));
   }

}
