/*
 * Created on 17-Feb-2005
 *
 */
package org.jboss.cache.optimistic;

import org.jboss.cache.Fqn;
import org.jboss.cache.GlobalTransaction;
import org.jboss.cache.TransactionTable;
import org.jboss.cache.TreeCache;
import org.jboss.cache.misc.TestingUtil;
import org.jboss.cache.loader.SamplePojo;
import org.jboss.cache.transaction.DummyTransactionManager;

import javax.transaction.Transaction;

/**
 * @author xenephon
 */
public class AsyncCacheTest extends AbstractOptimisticTestCase
{

    public AsyncCacheTest(String s)
    {
        super(s);
    }

    public void testRemoteCacheBroadcast() throws Exception
    {


        TreeCache cache = createReplicatedCache(TreeCache.REPL_ASYNC);
        TreeCache cache2 = createReplicatedCache(TreeCache.REPL_ASYNC);

        DummyTransactionManager mgr = DummyTransactionManager.getInstance();

        //start local transaction
        mgr.begin();
        Transaction tx = mgr.getTransaction();

        //this sets
        GlobalTransaction gtx = cache.getCurrentTransaction(tx);

        SamplePojo pojo = new SamplePojo(21, "test");

        cache.put("/one/two", "key1", pojo);

        //GlobalTransaction gtx = cache.getCurrentTransaction(tx);
        TransactionTable table = cache.getTransactionTable();
        assertNotNull(mgr.getTransaction());
        mgr.commit();


        assertNull(mgr.getTransaction());

        //assert that the local cache is in the right state
        assertEquals(0, cache.getTransactionTable().getNumGlobalTransactions());
        assertEquals(0, cache.getTransactionTable().getNumLocalTransactions());

        assertTrue(cache.exists(Fqn.fromString("/one/two")));
        assertTrue(cache.exists(Fqn.fromString("/one")));
        assertEquals(pojo, cache.get(Fqn.fromString("/one/two"), "key1"));

        // allow changes to replicate since this is async
        TestingUtil.sleepThread((long)1000);

        assertEquals(0, cache2.getTransactionTable().getNumGlobalTransactions());
        assertEquals(0, cache2.getTransactionTable().getNumLocalTransactions());

        assertTrue(cache2.exists(Fqn.fromString("/one/two")));
        assertTrue(cache2.exists(Fqn.fromString("/one")));
        assertEquals(pojo, cache2.get(Fqn.fromString("/one/two"), "key1"));


        destroyCache(cache);
        destroyCache(cache2);
    }


    public void testTwoWayRemoteCacheBroadcast() throws Exception
    {


        TreeCache cache = createReplicatedCache(TreeCache.REPL_ASYNC);
        TreeCache cache2 = createReplicatedCache(TreeCache.REPL_ASYNC);

        DummyTransactionManager mgr = DummyTransactionManager.getInstance();

        //start local transaction
        mgr.begin();
        Transaction tx = mgr.getTransaction();

        //this sets
        cache.getCurrentTransaction(tx);

        SamplePojo pojo = new SamplePojo(21, "test");

        cache.put("/one/two", "key1", pojo);

        GlobalTransaction gtx = cache.getCurrentTransaction(tx);
        TransactionTable table = cache.getTransactionTable();
        assertNotNull(mgr.getTransaction());
        mgr.commit();


        assertNull(mgr.getTransaction());

        //assert that the local cache is in the right state
        assertEquals(0, cache.getTransactionTable().getNumGlobalTransactions());
        assertEquals(0, cache.getTransactionTable().getNumLocalTransactions());

        assertTrue(cache.exists(Fqn.fromString("/one/two")));
        assertTrue(cache.exists(Fqn.fromString("/one")));
        assertEquals(pojo, cache.get(Fqn.fromString("/one/two"), "key1"));

        // let the async calls complete
        TestingUtil.sleepThread((long)1000);

        assertEquals(0, cache2.getTransactionTable().getNumGlobalTransactions());
        assertEquals(0, cache2.getTransactionTable().getNumLocalTransactions());

        assertTrue(cache2.exists(Fqn.fromString("/one/two")));
        assertTrue(cache2.exists(Fqn.fromString("/one")));

        assertEquals(pojo, cache2.get(Fqn.fromString("/one/two"), "key1"));


        destroyCache(cache);
        destroyCache(cache2);


    }
}
