package org.jboss.cache;

import junit.framework.Assert;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jboss.cache.factories.InterceptorChainFactory;
import org.jboss.cache.interceptors.*;
import org.jboss.cache.xml.XmlHelper;
import org.w3c.dom.Element;

import java.util.List;

/**
 * Created by IntelliJ IDEA.
 * User: bela
 * Date: Jun 9, 2004
 * Time: 9:05:19 AM
 */
public class InterceptorConfigurationTest extends TestCase
{
   TreeCache cache = null;

   protected void setUp() throws Exception
   {
      super.setUp();
      cache = new TreeCache();
      cache.setCacheMode(TreeCache.LOCAL);
   }

   protected void tearDown() throws Exception
   {
      super.tearDown();
      if (cache != null)
      {
         cache.stopService();
         cache.destroyService();
      }
   }


   public void testBareConfig() throws Exception
   {
      cache.setUseInterceptorMbeans(false);
      Interceptor chain = new InterceptorChainFactory().buildInterceptorChain(cache);
      List list = InterceptorChainFactory.asList(chain);
      System.out.println("testBareConfig interceptors are:\n" + list);
      assertNotNull(list);
      assertEquals(4, list.size());
      assertEquals(list.get(0).getClass(), TxInterceptor.class);
      assertEquals(list.get(1).getClass(), UnlockInterceptor.class);
      assertEquals(list.get(2).getClass(), PessimisticLockInterceptor.class);
      assertEquals(list.get(3).getClass(), CallInterceptor.class);
   }


   public void testTxConfig() throws Exception
   {
      cache.setUseInterceptorMbeans(false);
      cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");

      Interceptor chain = new InterceptorChainFactory().buildInterceptorChain(cache);
      List list = InterceptorChainFactory.asList(chain);
      System.out.println("testTxConfig interceptors are:\n" + list);
      assertNotNull(list);
      assertEquals(4, list.size());
      assertEquals(list.get(0).getClass(), TxInterceptor.class);
      assertEquals(list.get(1).getClass(), UnlockInterceptor.class);
      assertEquals(list.get(2).getClass(), PessimisticLockInterceptor.class);
      assertEquals(list.get(3).getClass(), CallInterceptor.class);
   }

   protected Element getCacheLoaderConfig(boolean pasv, boolean fetchPersistentState) throws Exception
   {
      String xml = "            <config>\n" +
              "                \n" +
              "                <passivation>" + pasv + "</passivation>\n" +
              "                <preload></preload>\n" +
              "\n" +
              "                <cacheloader>\n" +
              "                    <class>org.jboss.cache.loader.FileCacheLoader</class>\n" +
              "                    <properties>\n" +
              "                        location=/tmp\n" +
              "                    </properties>\n" +
              "                    <async>false</async>\n" +
              "                    <fetchPersistentState>" + fetchPersistentState + "</fetchPersistentState>\n" +
              "                    <ignoreModifications>false</ignoreModifications>\n" +
              "                </cacheloader>\n" +
              "                \n" +
              "            </config>";
      return XmlHelper.stringToElement(xml);
   }

   public void testSharedCacheLoaderConfig() throws Exception
   {
      cache.setUseInterceptorMbeans(false);
      cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
      cache.setCacheLoaderConfiguration(getCacheLoaderConfig(false, false));
      cache.setCacheMode(TreeCache.REPL_ASYNC);
      cache.setFetchInMemoryState(false);
      cache.createService();
      Interceptor chain = new InterceptorChainFactory().buildInterceptorChain(cache);
      List list = InterceptorChainFactory.asList(chain);
      System.out.println("testSharedCacheLoaderConfig interceptors are:\n" + list);
      assertNotNull(list);

      assertEquals(7, list.size());

      int i = 0;
      assertEquals(list.get(i++).getClass(), TxInterceptor.class);
      assertEquals(list.get(i++).getClass(), CacheStoreInterceptor.class);
      assertEquals(list.get(i++).getClass(), ReplicationInterceptor.class);
      assertEquals(list.get(i++).getClass(), UnlockInterceptor.class);
      assertEquals(list.get(i++).getClass(), CacheLoaderInterceptor.class);
      assertEquals(list.get(i++).getClass(), PessimisticLockInterceptor.class);
      assertEquals(list.get(i++).getClass(), CallInterceptor.class);
   }

   public void testUnsharedCacheLoaderConfig() throws Exception
   {
      cache.setUseInterceptorMbeans(false);
      cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
      cache.setCacheLoaderConfiguration(getCacheLoaderConfig(false, true));
      cache.setCacheMode(TreeCache.REPL_ASYNC);
      cache.setFetchInMemoryState(false);
      cache.createService();
      Interceptor chain = new InterceptorChainFactory().buildInterceptorChain(cache);
      List list = InterceptorChainFactory.asList(chain);
      System.out.println("testUnsharedCacheLoaderConfig interceptors are:\n" + list);
      assertNotNull(list);

      assertEquals(7, list.size());

      int i = 0;
      assertEquals(list.get(i++).getClass(), TxInterceptor.class);
      assertEquals(list.get(i++).getClass(), ReplicationInterceptor.class);
      assertEquals(list.get(i++).getClass(), UnlockInterceptor.class);
      assertEquals(list.get(i++).getClass(), CacheLoaderInterceptor.class);
      assertEquals(list.get(i++).getClass(), CacheStoreInterceptor.class);
      assertEquals(list.get(i++).getClass(), PessimisticLockInterceptor.class);
      assertEquals(list.get(i++).getClass(), CallInterceptor.class);
   }

   public void testTxAndRepl() throws Exception
   {
      cache.setUseInterceptorMbeans(false);
      cache.setCacheMode("repl_sync");
      cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
      Interceptor chain = new InterceptorChainFactory().buildInterceptorChain(cache);
      List list = InterceptorChainFactory.asList(chain);
      System.out.println("testTxAndRepl interceptors are:\n" + list);
      assertNotNull(list);

      assertEquals(5, list.size());

      int i = 0;
      assertEquals(list.get(i++).getClass(), TxInterceptor.class);
      assertEquals(list.get(i++).getClass(), ReplicationInterceptor.class);
      assertEquals(list.get(i++).getClass(), UnlockInterceptor.class);
      assertEquals(list.get(i++).getClass(), PessimisticLockInterceptor.class);
      assertEquals(list.get(i++).getClass(), CallInterceptor.class);
   }


   public void testOptimisticChain() throws Exception
   {
      TreeCache cache = new TreeCache();
      cache.setUseInterceptorMbeans(false);
      cache.setNodeLockingOptimistic(true);

      Interceptor next = new InterceptorChainFactory().buildInterceptorChain(cache);

      // test the chain size.
      List chainAsList = InterceptorChainFactory.asList(next);
      Assert.assertEquals(6, chainAsList.size());

      Assert.assertEquals(TxInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticLockingInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticValidatorInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticCreateIfNotExistsInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticNodeInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(CallInterceptor.class, next.getClass());
   }

   public void testOptimisticReplicatedChain() throws Exception
   {
      TreeCache cache = new TreeCache();
      cache.setUseInterceptorMbeans(false);
      cache.setNodeLockingOptimistic(true);
      cache.setCacheMode("REPL_SYNC");

      Interceptor next = new InterceptorChainFactory().buildInterceptorChain(cache);

      // test the chain size.
      List chainAsList = InterceptorChainFactory.asList(next);
      Assert.assertEquals(7, chainAsList.size());

      Assert.assertEquals(TxInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticReplicationInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticLockingInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticValidatorInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticCreateIfNotExistsInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticNodeInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(CallInterceptor.class, next.getClass());
   }

   public void testOptimisticCacheLoaderChain() throws Exception
   {
      TreeCache cache = new TreeCache();
      cache.setUseInterceptorMbeans(false);
      cache.setNodeLockingOptimistic(true);
      cache.setCacheLoaderConfiguration(getCacheLoaderConfig(false, false));
      cache.createService();
      Interceptor next = new InterceptorChainFactory().buildInterceptorChain(cache);

      // test the chain size.
      List chainAsList = InterceptorChainFactory.asList(next);
      Assert.assertEquals(8, chainAsList.size());


      Assert.assertEquals(TxInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(CacheStoreInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(CacheLoaderInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticLockingInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticValidatorInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticCreateIfNotExistsInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticNodeInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(CallInterceptor.class, next.getClass());
   }

   public void testOptimisticPassivationCacheLoaderChain() throws Exception
   {
      TreeCache cache = new TreeCache();
      cache.setUseInterceptorMbeans(false);
      cache.setNodeLockingOptimistic(true);
      cache.setCacheLoaderConfiguration(getCacheLoaderConfig(true, false));
      cache.createService();
      Interceptor next = new InterceptorChainFactory().buildInterceptorChain(cache);

      // test the chain size.
      List chainAsList = InterceptorChainFactory.asList(next);
      Assert.assertEquals(8, chainAsList.size());


      Assert.assertEquals(TxInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(PassivationInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(ActivationInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticLockingInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticValidatorInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticCreateIfNotExistsInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(OptimisticNodeInterceptor.class, next.getClass());
      next = next.getNext();
      Assert.assertEquals(CallInterceptor.class, next.getClass());
   }

   public void testInvalidationInterceptorChain() throws Exception
   {
      TreeCache cache = new TreeCache();
      cache.setUseInterceptorMbeans(false);
      cache.setCacheMode(TreeCache.REPL_ASYNC);

      Interceptor chain = new InterceptorChainFactory().buildInterceptorChain(cache);

      // test the chain size.
      List chainAsList = InterceptorChainFactory.asList(chain);
      Assert.assertEquals(5, chainAsList.size());

      Assert.assertEquals(TxInterceptor.class, chain.getClass());
      chain = chain.getNext();
      Assert.assertEquals(ReplicationInterceptor.class, chain.getClass());
      chain = chain.getNext();
      Assert.assertEquals(UnlockInterceptor.class, chain.getClass());
      chain = chain.getNext();
      Assert.assertEquals(PessimisticLockInterceptor.class, chain.getClass());
      chain = chain.getNext();
      Assert.assertEquals(CallInterceptor.class, chain.getClass());

      // ok, my replication chain looks good.

      // now for my invalidation chain.
      cache = new TreeCache();
      cache.setUseInterceptorMbeans(false);
      cache.setCacheMode(TreeCache.INVALIDATION_ASYNC);
      chain = new InterceptorChainFactory().buildInterceptorChain(cache);

      // test the chain size.
      chainAsList = InterceptorChainFactory.asList(chain);
      Assert.assertEquals(5, chainAsList.size());

      Assert.assertEquals(TxInterceptor.class, chain.getClass());
      chain = chain.getNext();
      Assert.assertEquals(InvalidationInterceptor.class, chain.getClass());
      chain = chain.getNext();
      Assert.assertEquals(UnlockInterceptor.class, chain.getClass());
      chain = chain.getNext();
      Assert.assertEquals(PessimisticLockInterceptor.class, chain.getClass());
      chain = chain.getNext();
      Assert.assertEquals(CallInterceptor.class, chain.getClass());
   }

   public void testCacheMgmtConfig() throws Exception
   {
      cache.setUseInterceptorMbeans(true);
      Interceptor chain = new InterceptorChainFactory().buildInterceptorChain(cache);
      List list = InterceptorChainFactory.asList(chain);
      System.out.println("testCacheMgmtConfig interceptors are:\n" + list);
      assertNotNull(list);
      assertEquals(5, list.size());
      assertEquals(list.get(0).getClass(), CacheMgmtInterceptor.class);
      assertEquals(list.get(1).getClass(), TxInterceptor.class);
      assertEquals(list.get(2).getClass(), UnlockInterceptor.class);
      assertEquals(list.get(3).getClass(), PessimisticLockInterceptor.class);
      assertEquals(list.get(4).getClass(), CallInterceptor.class);
   }

   public void testEvictionInterceptorConfig() throws Exception
   {
      cache.setIsUsingEviction(true);
      Interceptor chain = new InterceptorChainFactory().buildInterceptorChain(cache);
      List list = InterceptorChainFactory.asList(chain);
      System.out.println("testEvictionInterceptorConfig interceptors are:\n" + list);
      assertNotNull(list);
      assertEquals(6, list.size());
      assertEquals(list.get(0).getClass(), CacheMgmtInterceptor.class);
      assertEquals(list.get(1).getClass(), TxInterceptor.class);
      assertEquals(list.get(2).getClass(), UnlockInterceptor.class);
      assertEquals(list.get(3).getClass(), PessimisticLockInterceptor.class);
      assertEquals(list.get(4).getClass(), EvictionInterceptor.class);
      assertEquals(list.get(5).getClass(), CallInterceptor.class);
   }

   public void testBuddyReplicationOptLocking() throws Exception
   {
      String xmlString = "<config><buddyReplicationEnabled>true</buddyReplicationEnabled>\n" +
              "<buddyCommunicationTimeout>600000</buddyCommunicationTimeout>\n" +
              "          <buddyLocatorClass>org.jboss.cache.buddyreplication.NextMemberBuddyLocator</buddyLocatorClass>\n" +
              "          <buddyLocatorProperties>numBuddies = 1</buddyLocatorProperties>\n";

      xmlString += "<buddyPoolName>buddyPoolName</buddyPoolName>";
      xmlString += "</config>";
      cache.setCacheMode("REPL_SYNC");
      cache.setBuddyReplicationConfig(XmlHelper.stringToElement(xmlString));
      cache.setNodeLockingScheme("OPTIMISTIC");

      Interceptor chain = new InterceptorChainFactory().buildInterceptorChain(cache);

      List list = InterceptorChainFactory.asList(chain);
      System.out.println("testEvictionInterceptorConfig interceptors are:\n" + list);
      assertNotNull(list);
      assertEquals(9, list.size());
      int i = 0;
      assertEquals(list.get(i++).getClass(), CacheMgmtInterceptor.class);
      assertEquals(list.get(i++).getClass(), TxInterceptor.class);
      assertEquals(list.get(i++).getClass(), OptimisticReplicationInterceptor.class);
      assertEquals(list.get(i++).getClass(), DataGravitatorInterceptor.class);
      assertEquals(list.get(i++).getClass(), OptimisticLockingInterceptor.class);
      assertEquals(list.get(i++).getClass(), OptimisticValidatorInterceptor.class);
      assertEquals(list.get(i++).getClass(), OptimisticCreateIfNotExistsInterceptor.class);
      assertEquals(list.get(i++).getClass(), OptimisticNodeInterceptor.class);
      assertEquals(list.get(i++).getClass(), CallInterceptor.class);

   }

   public void testBuddyReplicationPessLocking() throws Exception
   {
      String xmlString = "<config><buddyReplicationEnabled>true</buddyReplicationEnabled>\n" +
              "<buddyCommunicationTimeout>600000</buddyCommunicationTimeout>\n" +
              "          <buddyLocatorClass>org.jboss.cache.buddyreplication.NextMemberBuddyLocator</buddyLocatorClass>\n" +
              "          <buddyLocatorProperties>numBuddies = 1</buddyLocatorProperties>\n";

      xmlString += "<buddyPoolName>buddyPoolName</buddyPoolName>";
      xmlString += "</config>";
      cache.setCacheMode("REPL_SYNC");
      cache.setBuddyReplicationConfig(XmlHelper.stringToElement(xmlString));

      Interceptor chain = new InterceptorChainFactory().buildInterceptorChain(cache);

      List list = InterceptorChainFactory.asList(chain);
      System.out.println("testEvictionInterceptorConfig interceptors are:\n" + list);
      assertNotNull(list);
      assertEquals(7, list.size());
      int i = 0;
      assertEquals(list.get(i++).getClass(), CacheMgmtInterceptor.class);
      assertEquals(list.get(i++).getClass(), TxInterceptor.class);
      assertEquals(list.get(i++).getClass(), ReplicationInterceptor.class);
      assertEquals(list.get(i++).getClass(), UnlockInterceptor.class);
      assertEquals(list.get(i++).getClass(), DataGravitatorInterceptor.class);
      assertEquals(list.get(i++).getClass(), PessimisticLockInterceptor.class);
      assertEquals(list.get(i++).getClass(), CallInterceptor.class);

   }


   public static Test suite()
   {
      return new TestSuite(InterceptorConfigurationTest.class);
   }

   public static void main(String[] args)
   {
      junit.textui.TestRunner.run(suite());
   }

}
