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

package org.jboss.cache.pojo;

import static org.testng.AssertJUnit.assertEquals;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.naming.Context;

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

/**
 * Test for attach with existing pojo for bulkd remove for speed.
 *
 * @author Ben Wang
 */

@Test(groups = {"functional"})
public class ReplicatedPutWithBulkRemoveTest 
{
   Log log_ = LogFactory.getLog(ReplicatedPutWithBulkRemoveTest.class);
   PojoCache cache_;
   PojoCache cache1_;


   @BeforeMethod(alwaysRun = true)
   protected void setUp() throws Exception
   {
      Properties prop = new Properties();
      prop.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.cache.transaction.DummyContextFactory");
      boolean toStart = false;
      cache_ = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), toStart);
      cache1_ = PojoCacheFactory.createCache(UnitTestCacheConfigurationFactory.createConfiguration(CacheMode.REPL_SYNC), toStart);
      cache_.start();
      cache1_.start();
   }

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

   public void testPutPutLocal() throws Exception
   {
      log_.info("testPutPut() ....");
      Person test = new Person();
      test.setName("Ben");
      test.setAge(10);
      Address addr = new Address();
      addr.setZip(95123);
      addr.setCity("Sunnyvale");
      test.setAddress(addr);
      cache_.attach("/a", test);
      Person result = (Person) cache_.find("/a");
      assertEquals(" ", test, result);

      Person joe = new Person();
      joe.setName("joe");
      joe.setAge(20);
      cache_.attach("/a", joe);
      Person joe1 = (Person) cache_.find("/a");
      assertEquals("Age should be ", 20, joe1.getAge());

      assertEquals("Age should be ", 10, result.getAge());
      assertEquals("Zip should be ", 95123, result.getAddress().getZip());

      // Try to re-use the pojo
      cache_.attach("/a", test);
      Person result1 = (Person) cache_.find("/a");
      assertEquals("Zip should be ", 95123, result1.getAddress().getZip());

   }

   public void testPutPut() throws Exception
   {
      log_.info("testPutPut() ....");
      Person test = new Person();
      test.setName("Ben");
      test.setAge(10);
      Address addr = new Address();
      addr.setZip(95123);
      addr.setCity("Sunnyvale");
      test.setAddress(addr);
      cache_.attach("/a", test);
      Person result = (Person) cache_.find("/a");
      assertEquals(" ", test, result);

      Person result1 = (Person) cache1_.find("/a");
      assertEquals("Age should be ", 10, result1.getAge());
      assertEquals("Zip should be ", 95123, result1.getAddress().getZip());

      Person joe = new Person();
      joe.setName("joe");
      joe.setAge(20);
      cache_.attach("/a", joe);
      Person joe1 = (Person) cache_.find("/a");
      assertEquals("Age should be ", 20, joe1.getAge());

      assertEquals("Age should be ", 10, result.getAge());
      assertEquals("Zip should be ", 95123, result.getAddress().getZip());
   }

   Address getAddress(String city)
   {
      Address addr = new Address();
      addr.setCity(city);
      addr.setZip(95123);
      addr.setStreet("Sunnyvale");
      return addr;
   }

   public void testPutCollection() throws Exception
   {
      log_.info("testPutCollection() ....");
      Person p1 = new Person();
      p1.setName("Ben");
      p1.setAge(10);
      p1.setAddress(getAddress("Sunnyvale"));

      List<String> lang = new ArrayList<String>();
      lang.add("English");
      lang.add("Spanish");
      p1.setLanguages(lang);

      cache_.attach("/a", p1);
      Person result = (Person) cache_.find("/a");
      assertEquals(" ", p1, result);
      assertEquals("English", result.getLanguages().get(0));
      assertEquals("Spanish", result.getLanguages().get(1));

      Person result1 = (Person) cache1_.find("/a");
      assertEquals("Age should be ", 10, result1.getAge());
      assertEquals("Zip should be ", 95123, result1.getAddress().getZip());
      assertEquals("English", result1.getLanguages().get(0));
      assertEquals("Spanish", result1.getLanguages().get(1));

      Person p2 = new Person();
      p2.setName("joe");
      p2.setAge(20);
      List<String> lang2 = new ArrayList<String>();
      lang2.add("French");
      p2.setLanguages(lang2);

      cache_.attach("/a", p2);
      Person joe1 = (Person) cache_.find("/a");
      assertEquals("Age should be ", 20, joe1.getAge());
      assertEquals("French", joe1.getLanguages().get(0));

      // put p1 again
      cache_.attach("/a", p1);

      // remove p1
      Person p3 = (Person) cache_.detach("/a");
      assertEquals("Zip should be ", 95123, p3.getAddress().getZip());
      assertEquals("English", p3.getLanguages().get(0));
      assertEquals("Spanish", p3.getLanguages().get(1));

      assertEquals("Age should be ", 10, result.getAge());
      assertEquals("Zip should be ", 95123, result.getAddress().getZip());
      assertEquals("English", result.getLanguages().get(0));
      assertEquals("Spanish", result.getLanguages().get(1));      
   }




}
