/*
 * COM Java wrapper 
 *
 * Copyright 2014 by Andrew Ian William Griffin <griffin@beerdragon.co.uk>.
 * Released under the GNU General Public License.
 */
package uk.co.beerdragon.comjvm.stub;

import org.testng.Assert;
import org.testng.annotations.Test;

/**
 * Tests the {@link ByteCodeClassLoader} class.
 */
@Test
public class ByteCodeClassLoaderTest {

  private static final byte[] FOO_BYTE_CODE = new byte[] { (byte)0xCA, (byte)0xFE, (byte)0xBA,
      (byte)0xBE, 0x00, 0x00, 0x00, 0x33, 0x00, 0x0B, 0x07, 0x00, 0x02, 0x01, 0x00, 0x38, 0x75,
      0x6B, 0x2F, 0x63, 0x6F, 0x2F, 0x62, 0x65, 0x65, 0x72, 0x64, 0x72, 0x61, 0x67, 0x6F, 0x6E,
      0x2F, 0x63, 0x6F, 0x6D, 0x6A, 0x76, 0x6D, 0x2F, 0x73, 0x74, 0x75, 0x62, 0x2F, 0x42, 0x79,
      0x74, 0x65, 0x43, 0x6F, 0x64, 0x65, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x4C, 0x6F, 0x61, 0x64,
      0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x24, 0x46, 0x6F, 0x6F, 0x07, 0x00, 0x04, 0x01, 0x00,
      0x10, 0x6A, 0x61, 0x76, 0x61, 0x2F, 0x6C, 0x61, 0x6E, 0x67, 0x2F, 0x4F, 0x62, 0x6A, 0x65,
      0x63, 0x74, 0x01, 0x00, 0x0A, 0x53, 0x6F, 0x75, 0x72, 0x63, 0x65, 0x46, 0x69, 0x6C, 0x65,
      0x01, 0x00, 0x1C, 0x42, 0x79, 0x74, 0x65, 0x43, 0x6F, 0x64, 0x65, 0x43, 0x6C, 0x61, 0x73,
      0x73, 0x4C, 0x6F, 0x61, 0x64, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x2E, 0x6A, 0x61, 0x76,
      0x61, 0x01, 0x00, 0x0C, 0x49, 0x6E, 0x6E, 0x65, 0x72, 0x43, 0x6C, 0x61, 0x73, 0x73, 0x65,
      0x73, 0x07, 0x00, 0x09, 0x01, 0x00, 0x34, 0x75, 0x6B, 0x2F, 0x63, 0x6F, 0x2F, 0x62, 0x65,
      0x65, 0x72, 0x64, 0x72, 0x61, 0x67, 0x6F, 0x6E, 0x2F, 0x63, 0x6F, 0x6D, 0x6A, 0x76, 0x6D,
      0x2F, 0x73, 0x74, 0x75, 0x62, 0x2F, 0x42, 0x79, 0x74, 0x65, 0x43, 0x6F, 0x64, 0x65, 0x43,
      0x6C, 0x61, 0x73, 0x73, 0x4C, 0x6F, 0x61, 0x64, 0x65, 0x72, 0x54, 0x65, 0x73, 0x74, 0x01,
      0x00, 0x03, 0x46, 0x6F, 0x6F, 0x06, 0x00, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x02, 0x00, 0x05, 0x00, 0x00, 0x00, 0x02, 0x00, 0x06, 0x00, 0x07, 0x00,
      0x00, 0x00, 0x0A, 0x00, 0x01, 0x00, 0x01, 0x00, 0x08, 0x00, 0x0A, 0x06, 0x0A };

  // private interface Foo {
  // }
  //
  // public void getFooBytes () throws Exception {
  // final String resource = "/" + Foo.class.getName ().replace ('.', '/') + ".class";
  // System.out.println (resource);
  // final InputStream in = getClass ().getResourceAsStream (resource);
  // int b;
  // int c = 0;
  // System.out.print ("private static final byte[] FOO_BYTE_CODE = new byte[] {");
  // while ((b = in.read ()) != -1) {
  // if (c++ > 0) {
  // System.out.print (',');
  // }
  // System.out.print (' ');
  // if (b >= 128) {
  // System.out.print ("(byte)");
  // }
  // System.out.print ("0x");
  // if (b < 16) {
  // System.out.print ('0');
  // }
  // System.out.print (Integer.toHexString (b).toUpperCase ());
  // }
  // System.out.println (" };");
  // in.close ();
  // }

  /**
   * Tests converting a bytecode sequence into a Java class.
   */
  public void testRegisterAndLoad () {
    final ByteCodeClassLoader loader = new ByteCodeClassLoader (getClass ().getClassLoader ());
    final String name = getClass ().getName () + "$Foo";
    loader.register (name, FOO_BYTE_CODE);
    final Class<?> clazz = loader.loadClass (name);
    Assert.assertEquals (clazz.getName (), getClass ().getName () + "$Foo");
  }

  /**
   * Tests handling of an unknown class name.
   */
  @Test (expectedExceptions = IllegalArgumentException.class)
  public void testLoadUnregistered () {
    final ByteCodeClassLoader loader = new ByteCodeClassLoader (getClass ().getClassLoader ());
    loader.loadClass (getClass ().getName () + "$Bar");
  }

}
