/*
 * JBoss, the OpenSource J2EE webOS
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

package org.jboss.cache.marshall;

import junit.framework.TestCase;
import org.jboss.cache.Fqn;
import org.jboss.cache.Version;
import org.jgroups.blocks.MethodCall;

import java.lang.reflect.Method;

/**
 * Tests the "activate/inactivate" functionality of LegacyTreeCacheMarshaller.
 * 
 * @author <a href="mailto://brian.stansberry@jboss.com">Brian Stansberry</a>
 * @version $Revision$
 */
public class ActiveInactiveTest extends TestCase
{

   public void testDefaultActive() throws Exception
   {
      VersionAwareMarshaller testee = new VersionAwareMarshaller(new RegionManager(), false, true, Version.getVersionString(Version.getVersionShort()));
      assertFalse("Root is not active", testee.isInactive("/"));
      
      testee.inactivate("/a");
      assertFalse("Root is not active after inactivating subtree", 
                   testee.isInactive("/"));
      
      testee.activate("/a");
      assertFalse("Root is not active after activating subtree", 
            testee.isInactive("/"));
      
      RegionNameConflictException ex = null;
      try {
        testee.activate("/a/b");
      }
      catch (RegionNameConflictException e) {
         ex = e;
      }
      assertNull("No RegionNameConflictException against default region", ex);
      
      testee.inactivate("/");
      assertTrue("Root is inactive", testee.isInactive("/"));
      
      try {
         testee.activate("/a");
         fail("Did not throw RegionNameConflictException when overriding '/'");
       }
       catch (RegionNameConflictException e) {
          // good
       }
   }
   
   public void testDefaultInactive() throws Exception
   {
      VersionAwareMarshaller testee = new VersionAwareMarshaller(new RegionManager(), true, true, Version.getVersionString(Version.getVersionShort()));
      assertTrue("Root is not inactive", testee.isInactive("/"));
      
      testee.activate("/a");
      assertTrue("Root is not inactive after activating subtree", 
                   testee.isInactive("/"));
      
      testee.inactivate("/a");
      assertTrue("Root is not inactive after inactivating subtree", 
            testee.isInactive("/"));
      
      RegionNameConflictException ex = null;
      try {
        testee.inactivate("/a/b");
      }
      catch (RegionNameConflictException e) {
         ex = e;
      }
      assertNull("Caught RegionNameConflictException against default region", ex);
      
      testee.activate("/");
      assertFalse("Root is not active", testee.isInactive("/"));
   }
   
   public void testActivate() throws Exception
   {
      VersionAwareMarshaller defaultActive = new VersionAwareMarshaller(new RegionManager(), false, true, Version.getVersionString(Version.getVersionShort()));
      
      defaultActive.activate("/a");
      assertFalse("/a is not active after activating", 
                  defaultActive.isInactive("/a"));
      
      defaultActive.inactivate("/a");
      defaultActive.activate("/a");
      assertFalse("/a is not active after reactivating", 
                  defaultActive.isInactive("/a"));
      
      VersionAwareMarshaller defaultInactive = new VersionAwareMarshaller(new RegionManager(), true, true, Version.getVersionString(Version.getVersionShort()));
      
      defaultInactive.activate("/i");
      assertFalse("/i is not active after activating", 
                  defaultInactive.isInactive("/i"));
      assertFalse("/i/k is not active after activating /i", 
            defaultInactive.isInactive("/i/k"));
      
      defaultInactive.inactivate("/i");
      defaultInactive.activate("/i");
      assertFalse("/i is not active after reactivating", 
                  defaultInactive.isInactive("/i"));
   }

   public void testInactivate() throws Exception
   {
      
      VersionAwareMarshaller defaultInactive = new VersionAwareMarshaller(new RegionManager(), true, true, Version.getVersionString(Version.getVersionShort()));
      
      defaultInactive.inactivate("/i");
      assertTrue("/i is not inactive after inactivating", 
                  defaultInactive.isInactive("/i"));
      
      defaultInactive.activate("/i");
      defaultInactive.inactivate("/i");
      assertTrue("/i is not inactive after re-inactivating", 
                  defaultInactive.isInactive("/i"));
      
      VersionAwareMarshaller defaultActive = new VersionAwareMarshaller(new RegionManager(), false, true, Version.getVersionString(Version.getVersionShort()));
      
      defaultActive.inactivate("/a");
      assertTrue("/a is not inactive after inactivating", 
                  defaultInactive.isInactive("/a"));
      assertTrue("/a/b is not inactive after inactivating /a", 
                  defaultInactive.isInactive("/a/b"));
      
      defaultActive.activate("/a");
      defaultActive.inactivate("/a");
      assertTrue("/a is not inactive after re-inactivating", 
                  defaultInactive.isInactive("/a"));
   }

   public void testObjectFromByteBuffer() throws Exception
   {
      MethodCall put = MethodCallFactory.create(MethodDeclarations.putKeyValMethodLocal,
            new Object[] { null, Fqn.fromString("/a/b"), "name", "Joe", Boolean.FALSE });
      
      MethodCall replicate = MethodCallFactory.create(MethodDeclarations.replicateMethod, new Object[] { put });

      VersionAwareMarshaller testee = new VersionAwareMarshaller(new RegionManager(), true, true, Version.getVersionString(Version.getVersionShort()));
      byte[] callBytes = testee.objectToByteBuffer(replicate);
      
      MethodCall result = (MethodCall) testee.objectFromByteBuffer(callBytes);
      Method method = result.getMethod();
      assertEquals("Did not get notifyCallOnInactive method when passing" +
            " call for inactive node", MethodDeclarations.notifyCallOnInactiveMethod, method);
      
      testee.activate("/a");
      result = (MethodCall) testee.objectFromByteBuffer(callBytes);
      method = result.getMethod();
      assertEquals("Did not get replicate method when passing" +
            " call for active node", MethodDeclarations.replicateMethod, method);
   }

}
