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

package org.jboss.cache.statetransfer;

import org.jboss.cache.DataNode;
import org.jboss.cache.Fqn;
import org.jboss.cache.TreeCache;
import org.jboss.cache.TreeCacheMBean;
import org.jboss.cache.buddyreplication.BuddyManager;
import org.jboss.cache.config.Option;
import org.jboss.cache.misc.TestingUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

/**
 * Tests that state transfer works properly if the version is 1.4.0.GA.
 * 
 * @author <a href="mailto://brian.stansberry@jboss.com">Brian Stansberry</a>
 * @version $Revision$
 */
public class StateTransfer140Test extends VersionedTestBase
{

   protected String getReplicationVersion()
   {
      return "1.4.0.GA";
   }

   public void testBuddyBackupExclusion() throws Exception
   {
      TreeCacheMBean cache1 = createCache("cache1", false, false, false, false, false);
   
      cache1.setBuddyReplicationConfig(getBuddyConfig());
      
      cache1.startService();
      
      Fqn backup = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, "test");
      // force this to be a LOCAL MODE put to prevent breakage
      Option o = new Option();
      o.setCacheModeLocal(true);
      cache1.put(backup, "name", JOE, o);
      cache1.put("/a/b", "age", TWENTY);
      
      TreeCacheMBean cache2 = createCache("cache2", false, false, false);
      
      // Pause to give caches time to see each other
      TestingUtil.blockUntilViewsReceived(new TreeCacheMBean[] { cache1, cache2 }, 60000);
      
      assertNull("_buddy_backup_ not transferred", cache2.get(backup, "name"));
      assertEquals("Correct age for /a/b", TWENTY, cache2.get("/a/b", "age"));
   }

   public void testBuddyIntegration() throws Exception
   {
      TreeCache cache1 = (TreeCache) createCache("cache1", false, false, false, false, false);
   
      cache1.setBuddyReplicationConfig(getBuddyConfig());
      
      cache1.startService();
      
      TreeCache cache2 = (TreeCache) createCache("cache2", false, false, false);
      
      // Pause to give caches time to see each other
      TestingUtil.blockUntilViewsReceived(new TreeCacheMBean[] { cache1, cache2 }, 60000);
      
      Option option = new Option();
      option.setCacheModeLocal(true);
      
      Fqn backup = Fqn.fromString(BuddyManager.BUDDY_BACKUP_SUBTREE);
      backup = new Fqn(backup, "a");
      cache1.put(backup, null, option);
      DataNode target = cache1.get(backup);
      
      Fqn abc = Fqn.fromString("/a/b/c");
      cache2.put(abc, "name", JOE, option);
      Fqn ad = Fqn.fromString("/a/d");
      cache2.put(ad, "name", JANE, option);
      
      Object[] sources = cache1.getMembers().toArray();
      ClassLoader cl = Thread.currentThread().getContextClassLoader();
      Fqn a = Fqn.fromString("/a");
      cache1._loadState(a, target, sources, cl);
      
      Fqn test = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, abc);
      assertEquals("/a/b/c state integrated in backup region", JOE, cache1.get(test, "name"));
      
      test = new Fqn(BuddyManager.BUDDY_BACKUP_SUBTREE_FQN, ad);
      assertEquals("/a/d state integrated in backup region", JANE, cache1.get(test, "name"));
   }
   
   
   
   private Element getBuddyConfig() throws Exception
   {
      DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
      DocumentBuilder db = dbf.newDocumentBuilder();
      Document doc = db.newDocument();
      Element config = doc.createElement("config");
      doc.appendChild(config);
      Element enabled = doc.createElement("buddyReplicationEnabled");
      enabled.appendChild(doc.createTextNode("true"));
      config.appendChild(enabled);
      Element pool = doc.createElement("buddyPoolName");
      pool.appendChild(doc.createTextNode("TEST"));
      config.appendChild(pool);
      return config;
   }
}
