package org.jboss.cache.marshall;

import org.jboss.cache.CacheSPI;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.Region;
import org.jboss.cache.util.TestingUtil;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

@Test(groups = {"functional", "jgroups"})
public class ReplicateToInactiveRegionTest
{
   CacheSPI[] caches;

   @BeforeMethod(alwaysRun = true)
   public void setUp() throws Exception
   {
      caches = new CacheSPI[]{createCache(), createCache()};
      TestingUtil.blockUntilViewsReceived(caches, 10000);
   }

   @AfterMethod(alwaysRun = true)
   public void tearDown() throws Exception
   {
      destroyCache(caches[0]);
      destroyCache(caches[1]);
      caches = null;
   }

   private void destroyCache(CacheSPI c)
   {
      c.stop();
   }

   private CacheSPI createCache()
   {
      CacheSPI c = (CacheSPI) new DefaultCacheFactory().createCache(false);
      c.getConfiguration().setCacheMode("REPL_SYNC");
      c.getConfiguration().setUseRegionBasedMarshalling(true);
      c.start();
      return c;
   }

   @SuppressWarnings("unchecked")
   public void testTransferToInactiveRegion()
   {
      Fqn f = Fqn.fromString("/a/b");

      caches[0].put(f, "k", "v");

      assertEquals("v", caches[0].get(f, "k"));
      assertEquals("v", caches[1].get(f, "k"));

      // create the region on cache 0, make sure it is marked as a MARSHALLING region by attaching a class loader to it.
      Region region0 = caches[0].getRegionManager().getRegion(f, true);
      region0.registerContextClassLoader(this.getClass().getClassLoader()); // just to make sure this is recognised as a marshalling region.
      assertTrue("Should be active by default", region0.isActive());
      // make sure this newly created region is "recognised" as a marshalling region.
      assertTrue(caches[0].getRegionManager().getAllRegions(Region.Type.MARSHALLING).contains(region0));

      // now create a region on cache 1, as above.
      Region region1 = caches[1].getRegionManager().getRegion(f, true);
      region1.registerContextClassLoader(this.getClass().getClassLoader()); // just to make sure this is recognised as a marshalling region.
      assertTrue("Should be active by default", region1.isActive());
      // make sure this newly created region is "recognised" as a marshalling region.
      assertTrue(caches[1].getRegionManager().getAllRegions(Region.Type.MARSHALLING).contains(region1));

      // now deactivate the region on cache 1.
      region1.deactivate();
      assertFalse("Should be have deactivated", region1.isActive());

      caches[0].put(f, "k", "v2");
      assertEquals("v2", caches[0].get(f, "k"));
      assertNull(caches[1].get(f, "k"));

   }
}

