package org.jboss.cache.marshall;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.jboss.cache.Fqn;
import org.jboss.cache.TreeCache;
import org.jboss.cache.lock.IsolationLevel;

import javax.transaction.Transaction;
import java.io.File;
import java.net.URL;
import java.net.URLClassLoader;
import java.lang.reflect.Method;

/**
 * Simple functional tests for LegacyTreeCacheMarshaller
 * @author Ben Wang
 * @version $Id: LocalTest.java 2045 2006-06-07 22:28:08Z msurtani $
 */
public class LocalTest extends TestCase {
   TreeCache cache=null;
   Transaction tx=null;
   final Fqn FQN=Fqn.fromString("/myNode");
   final String KEY="key";
   final String VALUE="value";
   Exception ex;


   protected void setUp() throws Exception {
      super.setUp();
      cache=new TreeCache();
      cache.setCacheMode(TreeCache.LOCAL);
      cache.setTransactionManagerLookupClass("org.jboss.cache.DummyTransactionManagerLookup");
      cache.setIsolationLevel(IsolationLevel.REPEATABLE_READ);
      cache.createService();
      cache.startService();
      ex=null;
   }

   protected void tearDown() throws Exception {
      super.tearDown();
      if(cache != null) {
         cache.stopService();
         cache.destroyService();
         cache=null;
      }
      if(ex != null)
         throw ex;
   }

   public void testClassloader() throws Exception {
      String jarDir = System.getProperty("test.jar.dir");
      File jar0 = new File(jarDir+ "/testMarshall.jar");
      URL[] cp0 = {jar0.toURL()};
      URLClassLoader ucl0 = new URLClassLoader(cp0);
      Thread.currentThread().setContextClassLoader(ucl0);
      Class clasz1 = ucl0.loadClass("org.jboss.cache.marshall.Person");
      StringBuffer buffer = new StringBuffer("Person Info");
      Debug.displayClassInfo(clasz1, buffer, false);
      log(buffer.toString());
      Object ben = clasz1.newInstance();
      Object value = null;
      try
      {
         {
         Class[] types = {String.class};
         Method setValue = clasz1.getMethod("setName", types);
         Object[] margs = {"Ben"};
         value = setValue.invoke(ben, margs);
         }
         Class[] types = {};
         Class[] margs = {};
         Method getValue = clasz1.getMethod("getName", types);
         value = getValue.invoke(ben, margs);
         buffer.setLength(0);
         buffer.append("main.obj.CodeSource: ");
         Debug.displayClassInfo(value.getClass(), buffer, false);
         log(buffer.toString());
      }
      catch(Exception e)
      {
         e.printStackTrace();
         log("Failed to invoke getName: " + e);
      }

      cache.put("/a/b/c", "ben", ben);
      assertNotNull(cache.get("/a/b/c"));
      assertEquals(cache.get("/a/b/c", "ben"), ben);
      Object obj = cache.get("/a/b/c", "ben");

      URLClassLoader ucl1 = new URLClassLoader(cp0);
      Class claszAddr = ucl0.loadClass("org.jboss.cache.marshall.Address");
      buffer = new StringBuffer("Address Info");
      Debug.displayClassInfo(claszAddr, buffer, false);
      log(buffer.toString());
      Object addr = claszAddr.newInstance();
      try
      {
         {
         Class[] types = {String.class};
         Method setValue = claszAddr.getMethod("setCity", types);
         Object[] margs = {"SF"};
         value = setValue.invoke(addr, margs);
         }

         {
         Class[] types = {claszAddr};
         Method setValue = clasz1.getMethod("setAddress", types);
         Object[] margs = {addr};
         value = setValue.invoke(obj, margs);
         }

         Class[] types = {};
         Class[] margs = {};
         Method getValue = clasz1.getMethod("getAddress", types);
         value = getValue.invoke(obj, margs);
         buffer.setLength(0);
         buffer.append("main.obj.CodeSource: ");
         Debug.displayClassInfo(value.getClass(), buffer, false);
         log(buffer.toString());
      }
      catch(Exception e)
      {
         e.printStackTrace();
         log("Failed to invoke: " + e);
         throw e;
      }

   }

   void log(String msg) {
      System.out.println("-- " + msg);
   }

   public static Test suite() {
      return new TestSuite(LocalTest.class);
   }

   //public static void main(String[] args) {
     // junit.textui.TestRunner.run(suite());
   //}

}
