/*
 * JBoss, Home of Professional Open Source
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */
package org.jboss.cache.buddyreplication;

import org.jboss.cache.CacheSPI;
import org.jboss.cache.DefaultCacheFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.config.BuddyReplicationConfig;
import org.jboss.cache.config.Configuration;
import org.jboss.cache.factories.XmlConfigurationParser;
import org.jboss.cache.interceptors.DataGravitatorInterceptor;
import org.jboss.cache.interceptors.base.CommandInterceptor;
import org.jboss.cache.xml.XmlHelper;
import static org.testng.AssertJUnit.*;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.Test;
import org.w3c.dom.Element;

/**
 * Tests basic configuration options by passing stuff into the CacheImpl.
 *
 * @author <a href="mailto:manik@jboss.org">Manik Surtani (manik@jboss.org)</a>
 */
@Test(groups = {"functional", "jgroups"})
public class BuddyReplicationConfigTest
{
   private CacheSPI<Object, Object> cache;

   @AfterMethod(alwaysRun = true)
   public void tearDown()
   {
      cache.stop();
      cache = null;
   }

   public void testNullConfig() throws Exception
   {
      cache = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
      cache.getConfiguration().setBuddyReplicationConfig(null);
      assertNull(cache.getBuddyManager());
   }

   public void testDisabledConfig() throws Exception
   {
      String xmlConfig = "<config><buddyReplicationEnabled>false</buddyReplicationEnabled></config>";
      Element element = XmlHelper.stringToElement(xmlConfig);
      BuddyReplicationConfig config = XmlConfigurationParser.parseBuddyReplicationConfig(element);
      cache = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
      cache.getConfiguration().setBuddyReplicationConfig(config);
      assertNull(cache.getBuddyManager());
   }

   public void testBasicConfig() throws Exception
   {
      String xmlConfig = "<config><buddyReplicationEnabled>true</buddyReplicationEnabled></config>";
      Element element = XmlHelper.stringToElement(xmlConfig);
      BuddyReplicationConfig config = XmlConfigurationParser.parseBuddyReplicationConfig(element);
      cache = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
      cache.getConfiguration().setCacheMode(Configuration.CacheMode.REPL_SYNC);
      cache.getConfiguration().setBuddyReplicationConfig(config);
      cache.create();
      cache.start();
      assertNotNull(cache.getBuddyManager());
      BuddyManager mgr = cache.getBuddyManager();
      assertTrue(mgr.isEnabled());
      assertNull(mgr.getBuddyPoolName());
      assertEquals(NextMemberBuddyLocator.class, mgr.buddyLocator.getClass());
      NextMemberBuddyLocatorConfig blc = (NextMemberBuddyLocatorConfig) mgr.buddyLocator.getConfig();
      assertEquals(1, blc.getNumBuddies());
      assertTrue(blc.isIgnoreColocatedBuddies());
   }

   public void testXmlConfig() throws Exception
   {
      cache = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(new XmlConfigurationParser().parseFile("META-INF/buddy-replication-cache-service.xml"), false);
      cache.create();
      cache.start();
      BuddyManager bm = cache.getBuddyManager();
      assertNotNull(bm);
      assertTrue(bm.isEnabled());
      assertTrue(bm.buddyLocator instanceof NextMemberBuddyLocator);
      NextMemberBuddyLocator bl = (NextMemberBuddyLocator) bm.buddyLocator;
      NextMemberBuddyLocatorConfig blc = (NextMemberBuddyLocatorConfig) bl.getConfig();
      assertTrue(blc.isIgnoreColocatedBuddies());
      assertEquals(1, blc.getNumBuddies());
      assertEquals("myBuddyPoolReplicationGroup", bm.getConfig().getBuddyPoolName());
      assertEquals(2000, bm.getConfig().getBuddyCommunicationTimeout());

      // test Data Gravitator
      boolean hasDG = false;
      for (CommandInterceptor interceptor : cache.getInterceptorChain())
      {
         hasDG = hasDG || (interceptor instanceof DataGravitatorInterceptor);
      }

      System.out.println(cache.getInterceptorChain());

      assertTrue("Should have a data gravitator!!", hasDG);
   }

   public void testLocalModeConfig() throws Exception
   {
      String xmlConfig = "<config><buddyReplicationEnabled>true</buddyReplicationEnabled></config>";
      Element element = XmlHelper.stringToElement(xmlConfig);
      BuddyReplicationConfig config = XmlConfigurationParser.parseBuddyReplicationConfig(element);
      cache = (CacheSPI<Object, Object>) new DefaultCacheFactory<Object, Object>().createCache(false);
      cache.getConfiguration().setBuddyReplicationConfig(config);
      cache.create();
      cache.start();
      assert cache.getBuddyManager() == null;

      cache.getInvocationContext().getOptionOverrides().setForceDataGravitation(true);
      cache.getNode(Fqn.fromString("/nonexistent")); // should not barf!
   }
}