/*
 * JBoss, Home of Professional Open Source
 *
 * Distributable under LGPL license.
 * See terms of license at gnu.org.
 */

package org.jboss.cache.pojo.region;

import static org.testng.AssertJUnit.assertEquals;
import static org.testng.AssertJUnit.assertNull;

import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jboss.cache.Fqn;
import org.jboss.cache.config.Configuration.CacheMode;
import org.jboss.cache.factories.UnitTestCacheConfigurationFactory;
import org.jboss.cache.pojo.PojoCache;
import org.jboss.cache.pojo.PojoCacheFactory;
import org.jboss.cache.pojo.test.Person;
import org.jboss.cache.pojo.test.Student;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

/**
 * Replicated test that use a tester wrapper. Future new test should use NewReplicatedAopTest
 *
 * @author Ben Wang
 */
@Test(groups = {"functional"})
public class ReplicatedTest
{
   Log log = LogFactory.getLog(org.jboss.cache.pojo.region.ReplicatedTest.class);
   PojoCache cache, cache1;



   @BeforeMethod(alwaysRun = true)
   protected void setUp() throws Exception
   {
      log.info("setUp() ....");
      boolean toStart = false;
      cache = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), toStart);
      cache.start();
      cache1 = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), toStart);
      cache1.start();
      cache.getCache().getRegion(Fqn.fromString("SESSION"), true);
      cache1.getCache().getRegion(Fqn.fromString("SESSION"), true);
   }

   @AfterMethod(alwaysRun = true)
   protected void tearDown() throws Exception
   {
      cache.stop();
      cache1.stop();
   }

//   public void testDummy() {}

   private Person createPerson(String id, String name, int age)
   {
      Person p = new Person();
      p.setName(name);
      p.setAge(age);
      cache.attach(id, p);
      return p;
   }

   private Student createStudent(String id, String name, int age, String grade)
   {
      Student p = new Student();
      p.setName(name);
      p.setAge(age);
      p.setYear(grade);
      cache.attach(id, p);
      return p;
   }

   public void testSimple() throws Exception
   {
      log.info("testSimple() ....");
      Person ben = createPerson("/person/test1", "Ben Wang", 40);
      assertEquals("Ben Wang", ben.getName());
      assertEquals("Ben Wang", ((Person) cache1.find("/person/test1")).getName());
      cache.detach("/person/test1");
   }


   public void testDynamicRefSwapping() throws Exception
   {
      Person person = createPerson("/person/test3", "Joe", 32);
      try
      {
         person.setAge(30);
         List<String> med = person.getMedication();
         assertNull("Medication should be null ", med);
         person.setAge(61);
         med = person.getMedication();
         assertEquals("Medication ", (Object) "Lipitor", (Object) med.get(0));
         assertEquals("Medication on cache1 ", "Lipitor",
                      person.getMedication().get(0));

         person.setAge(71);
         assertEquals("Medication ", "Vioxx", med.get(1));
         assertEquals("Medication on cache1 ", "Vioxx",
                      ((Person) cache1.find("/person/test3")).getMedication().get(1));
         cache.detach("/person/test3");

      }
      catch (Exception e)
      {
         // should be thrown
      }
   }

   public void testTransient() throws Exception
   {
      log.info("testTransient() ....");
      Person ben = createPerson("/person/test1", "Ben Wang", 40);
      ben.setCurrentStatus("Idle");
      assertEquals("Cache 1 ", "Idle", ben.getCurrentStatus());
      assertEquals("Cache 2 ", "Active",
                   ((Person) cache1.find("/person/test1")).getCurrentStatus());
      cache.detach("/person/test1");
   }

   public void testModification() throws Exception
   {
      Person ben = createPerson("/person/test2", "Ben Wang", 40);
      ben.setName("Harald Gliebe");
      assertEquals(ben.getName(), "Harald Gliebe");
      assertEquals(((Person) cache1.find("/person/test2")).getName(), "Harald Gliebe");
      cache.detach("/person/test2");
   }

   public void testInheritance() throws Exception
   {
      Student joe = createStudent("/person/joe", "Joe", 32, "Senior");
      joe.setName("Joe Black");
      assertEquals(joe.getName(), "Joe Black");
      Student joe1 = (Student) cache1.find("/person/joe");
      assertEquals(joe1.getName(), "Joe Black");
      joe1.setYear("Junior");
      assertEquals(joe.getYear(), "Junior");
      assertEquals(joe1.getYear(), "Junior");
      cache.detach("/person/joe");
      cache.detach("/person/joe");
   }





}
