package org.jboss.cache.aop.integrated;

import junit.framework.TestCase;
import org.jboss.cache.PropertyConfigurator;
import org.jboss.cache.aop.PojoCache;
import org.jboss.cache.aop.test.propagation.PropagationManager;
import org.jboss.cache.aop.test.propagation.impl.PropagationManagerImpl;

public class ReplicatedPropagationManagerlAopTest extends TestCase {
   private PropagationManager pm_;
   private PojoCache cache1_;
   private PojoCache cache2_;

   protected void setUp() throws Exception {
      cache1_ = createCache("TestCluster");
      cache2_ = createCache("TestCluster");
   }

   protected void tearDown() throws Exception {
      cache1_.remove("/");
      cache1_.stop();
      cache2_.stop();
   }

   private PojoCache createCache(String name) throws Exception {
      PojoCache tree = new PojoCache();
      PropertyConfigurator config = new PropertyConfigurator();
      config.configure(tree, "META-INF/replSync-service.xml"); // read in generic replAsync xml
      tree.setClusterName(name);
      tree.createService();
      tree.startService();
      return tree;
   }

   protected void initSimplifiedPm() {
      pm_ = new PropagationManagerImpl();

      pm_.setRootNode("root");
      pm_.addNode("root", "kanto");
      pm_.addNode("root.kanto", "tokyo");
      pm_.addStateItem("root.kanto.tokyo", 1000, 1040);
      pm_.addNode("root.kanto", "kanagawa");
/*
        pm_.addStateItem("root.kanto.tokyo", 1001, 1040);
        pm_.addStateItem("root.kanto.tokyo", 1002, 1040);
        pm_.addNode("root.kanto.tokyo", "shinjuku");
        pm_.addStateItem("root.kanto.tokyo.shinjuku", 1000, 1040);
        pm_.addStateItem("root.kanto.tokyo.shinjuku", 1001, 1040);
        pm_.addStateItem("root.kanto.tokyo.shinjuku", 1002, 1040);
        pm_.addNode("root.kanto.kanagawa", "kawasaki");
        pm_.addStateItem("root.kanto.kanagawa.kawasaki", 1005, 1040);
        pm_.addStateItem("root.kanto.kanagawa.kawasaki", 1006, 1040);
        pm_.addStateItem("root.kanto.kanagawa.kawasaki", 1007, 1030);
      System.out.println("\n\n");
      System.out.println("---------------------------------------------");
      System.out.println("Initial pm state");
      System.out.println("---------------------------------------------");
      pm_.printNodes();
*/
   }

   public void testSimplified() throws Exception {
      initSimplifiedPm();

      // Put pm into cache management first
      cache1_.putObject("/propagation", pm_);
      System.out.println("\n\n");
      System.out.println("---------------------------------------------");
      System.out.println("Initial cache content");
      System.out.println(cache1_.printDetails());
      System.out.println("---------------------------------------------");

      PropagationManager pm1 = (PropagationManager) cache2_.getObject("/propagation");
      assertEquals("PropagationManager should ", pm_.toString(), pm1.toString());

      System.out.println("\n\n");
      System.out.println("---------------------------------------------");
      System.out.println("root.kanto.kanagawa.kawasaki:1007  1030->1031");
      System.out.println("---------------------------------------------");
      pm_.stateChange("root.kanto.kanagawa.kawasaki", 1007, 1031);
      pm_.printNodes();

      /*
      System.out.println("\n\n");
      System.out.println("---------------------------------------------");
      System.out.println("Final cache content");
      System.out.println(cache_.printDetails());
      System.out.println("---------------------------------------------");
      */
   }

   protected void initPm() {
      pm_ = new PropagationManagerImpl();

      pm_.setRootNode("root");
      pm_.addNode("root", "kanto");
      pm_.addNode("root.kanto", "tokyo");
      pm_.addStateItem("root.kanto.tokyo", 1000, 1040);
      pm_.addStateItem("root.kanto.tokyo", 1001, 1040);
      pm_.addStateItem("root.kanto.tokyo", 1002, 1040);
      pm_.addNode("root.kanto.tokyo", "shinjuku");
      pm_.addStateItem("root.kanto.tokyo.shinjuku", 1000, 1040);
      pm_.addStateItem("root.kanto.tokyo.shinjuku", 1001, 1040);
      pm_.addStateItem("root.kanto.tokyo.shinjuku", 1002, 1040);
      pm_.addNode("root.kanto", "kanagawa");
      pm_.addNode("root.kanto.kanagawa", "kawasaki");
      pm_.addStateItem("root.kanto.kanagawa.kawasaki", 1005, 1040);
      pm_.addStateItem("root.kanto.kanagawa.kawasaki", 1006, 1040);
      pm_.addStateItem("root.kanto.kanagawa.kawasaki", 1007, 1030);
   }

   public void testPropagation() throws Exception {
      initPm();
      // Put pm into cache management first
      cache1_.putObject("/propagation", pm_);
      System.out.println("\n\n");
      System.out.println("---------------------------------------------");
      System.out.println("Initial cache content");
      System.out.println(cache1_.printDetails());
      System.out.println("---------------------------------------------");

      PropagationManager pm1 = (PropagationManager) cache2_.getObject("/propagation");
      assertEquals("PropagationManager should ", pm_.toString(), pm1.toString());

      System.out.println("\n\n");
      System.out.println("---------------------------------------------");
      System.out.println("Initial pm state");
      System.out.println("---------------------------------------------");
      pm_.printNodes();

      System.out.println("\n\n");
      System.out.println("---------------------------------------------");
      System.out.println("root.kanto.kanagawa.kawasaki:1007  1030->1031");
      System.out.println("---------------------------------------------");
      pm_.stateChange("root.kanto.kanagawa.kawasaki", 1007, 1031);
      pm_.printNodes();

      System.out.println("\n\n");
      System.out.println("---------------------------------------------");
      System.out.println("root.kanto.tokyo.shinjuku:1001  1040->1041");
      System.out.println("---------------------------------------------");
      pm_.stateChange("root.kanto.tokyo.shinjuku", 1001, 1041);
      pm_.printNodes();

      System.out.println("\n\n");
      System.out.println("---------------------------------------------");
      System.out.println("root.kanto.kanagawa.kawasaki:1006  1040->1041");
      System.out.println("---------------------------------------------");
      pm_.stateChange("root.kanto.kanagawa.kawasaki", 1006, 1041);
      pm_.printNodes();

      System.out.println("\n\n");
      System.out.println("---------------------------------------------");
      System.out.println("add new item to root.kanto.kanagawa.kawasaki:1008 default:1021");
      System.out.println("---------------------------------------------");
      pm_.addStateItem("root.kanto.kanagawa.kawasaki", 1008, 1021);
      pm_.printNodes();

      System.out.println("\n\n");
      System.out.println("---------------------------------------------");
      System.out.println("Final cache content");
      System.out.println(cache1_.printDetails());
      System.out.println("---------------------------------------------");
   }

   public static void main(String[] args) throws Exception {
      ReplicatedPropagationManagerlAopTest pmTest = new ReplicatedPropagationManagerlAopTest();
      pmTest.setUp();
      pmTest.testPropagation();
   }
}
