/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import org.apache.bcel.Const;
import org.apache.bcel.classfile.Utility;
import org.apache.bcel.generic.ALOAD;
import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.GETSTATIC;
import org.apache.bcel.generic.INVOKEVIRTUAL;
import org.apache.bcel.generic.InstructionConst;
import org.apache.bcel.generic.InstructionFactory;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.ObjectType;
import org.apache.bcel.generic.PUSH;
import org.apache.bcel.generic.Type;

/**
 * Dynamically creates and uses a proxy for {@link java.awt.event.ActionListener} via the class loader mechanism if
 * called with
 *
 * <pre>
 * java org.apache.bcel.util.JavaWrapper ProxyCreator
 * </pre>
 *
 * The trick is to encode the byte code we need into the class name using the Utility.encode() method. This will result
 * however in big ugly class name, so for many cases it will be more sufficient to put some clever creation code into
 * the class loader.
 * <p>
 * This is comparable to the mechanism provided via {@link java.lang.reflect.Proxy}, but much more flexible.
 * </p>
 *
 * @see org.apache.bcel.util.JavaWrapper
 * @see Utility
 */
public class ProxyCreator {

    /**
     * Load class and create instance
     */
    public static Object createProxy(final String pack, final String className) {
        try {
            final Class<?> cl = Class.forName(pack + "$$BCEL$$" + className);
            return cl.getConstructor().newInstance();
        } catch (final Exception e) {
            e.printStackTrace();
        }

        return null;
    }

    /**
     * Create JavaClass object for a simple proxy for an java.awt.event.ActionListener that just prints the passed
     * arguments, load and use it via the class loader mechanism.
     */
    public static void main(final String[] argv) throws Exception {
        final ClassLoader loader = ProxyCreator.class.getClassLoader();

        // instanceof won't work here ...
        // TODO this is broken; cannot ever be true now that ClassLoader has been dropped
        if (loader.getClass().toString().equals("class org.apache.bcel.util.ClassLoader")) {
            // Real class name will be set by the class loader
            final ClassGen cg = new ClassGen("foo", "java.lang.Object", "", Const.ACC_PUBLIC, new String[] {"java.awt.event.ActionListener"});

            // That's important, otherwise newInstance() won't work
            cg.addEmptyConstructor(Const.ACC_PUBLIC);

            final InstructionList il = new InstructionList();
            final ConstantPoolGen cp = cg.getConstantPool();
            final InstructionFactory factory = new InstructionFactory(cg);

            final int out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;");
            final int println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/Object;)V");
            final MethodGen mg = new MethodGen(Const.ACC_PUBLIC, Type.VOID, new Type[] {new ObjectType("java.awt.event.ActionEvent")}, null,
                "actionPerformed", "foo", il, cp);

            // System.out.println("actionPerformed:" + event);
            il.append(new GETSTATIC(out));
            il.append(factory.createNew("java.lang.StringBuffer"));
            il.append(InstructionConst.DUP);
            il.append(new PUSH(cp, "actionPerformed:"));
            il.append(factory.createInvoke("java.lang.StringBuffer", "<init>", Type.VOID, new Type[] {Type.STRING}, Const.INVOKESPECIAL));

            il.append(new ALOAD(1));
            il.append(factory.createAppend(Type.OBJECT));
            il.append(new INVOKEVIRTUAL(println));
            il.append(InstructionConst.RETURN);

            mg.stripAttributes(true);
            mg.setMaxStack();
            mg.setMaxLocals();
            cg.addMethod(mg.getMethod());

            final byte[] bytes = cg.getJavaClass().getBytes();

            System.out.println("Uncompressed class: " + bytes.length);

            final String s = Utility.encode(bytes, true);
            System.out.println("Encoded class: " + s.length());

            System.out.print("Creating proxy... ");
            final ActionListener a = (ActionListener) createProxy("foo.bar.", s);
            System.out.println("Done. Now calling actionPerformed()");

            a.actionPerformed(new ActionEvent(a, ActionEvent.ACTION_PERFORMED, "hello"));
        } else {
            System.err.println("Call me with java org.apache.bcel.util.JavaWrapper ProxyCreator");
        }
    }

}
