package org.jboss.cache.buddyreplication;

import org.jboss.cache.CacheSPI;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.util.TestingUtil;
import org.jboss.cache.config.EvictionConfig;
import org.jboss.cache.config.EvictionRegionConfig;
import org.jboss.cache.eviction.LRUConfiguration;
import org.jboss.cache.eviction.NullEvictionPolicy;
import org.testng.annotations.AfterTest;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;

import java.util.Collections;

/**
 * Tests the eviction of buddy backup regions
 *
 * @author Manik Surtani (<a href="mailto:manik@jboss.org">manik@jboss.org</a>)
 * @since 2.2.0
 */
@Test(groups = "functional")
public class EvictionOfBuddyBackupsTest extends BuddyReplicationTestsBase
{
   private CacheSPI cache1, cache2;
   private Fqn fqn = Fqn.fromString("/a/b/c");

   @BeforeTest
   public void setUp() throws Exception
   {
      cache1 = createCache(1, null, true, false);
      cache1.getConfiguration().setEvictionConfig(getEvictionConfig());
      cache1.start();

      cache2 = (CacheSPI) new DefaultCacheFactory().createCache(cache1.getConfiguration().clone());

      TestingUtil.blockUntilViewsReceived(60000, cache1, cache2);
   }

   @AfterTest
   public void tearDown()
   {
      TestingUtil.killCaches(cache1, cache2);
   }

   private EvictionConfig getEvictionConfig()
   {
      EvictionConfig c = new EvictionConfig();
      c.setDefaultEvictionPolicyClass(NullEvictionPolicy.class.getName());
      c.setWakeupIntervalSeconds(1);
      LRUConfiguration epc = new LRUConfiguration();
      epc.setMaxAgeSeconds(1);
      epc.setTimeToLiveSeconds(1);
      EvictionRegionConfig erc = new EvictionRegionConfig(fqn, epc);
      c.setEvictionRegionConfigs(Collections.singletonList(erc));
      return c;
   }


   public void testEvictionOfBackupRegions() throws Exception
   {
      cache1.put(fqn, "k", "v");
      assert cache1.peek(fqn, false, false) != null : "Node should exist";
      assert cache2.peek(fqnTransformer.getBackupFqn(cache1.getLocalAddress(), fqn), false, false) != null : "Node should exist on backup";

      // now wait for eviction to kick in - for up to 2 secs
      TestingUtil.sleepThread(2000);

      assert cache1.peek(fqn, false, false) == null : "Node should have evicted";
      assert cache2.peek(fqnTransformer.getBackupFqn(cache1.getLocalAddress(), fqn), false, false) == null : "Node should have evicted on backup";
   }
}
