/*
 * 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
 *
 *      http://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 org.apache.bcel.Constants;
import org.apache.bcel.classfile.ClassParser;
import org.apache.bcel.classfile.Code;
import org.apache.bcel.classfile.ConstantClass;
import org.apache.bcel.classfile.ConstantPool;
import org.apache.bcel.classfile.ConstantUtf8;
import org.apache.bcel.classfile.JavaClass;
import org.apache.bcel.classfile.Method;
import org.apache.bcel.classfile.Utility;
import org.apache.bcel.generic.ConstantPoolGen;
import org.apache.bcel.generic.GETSTATIC;
import org.apache.bcel.generic.INVOKESPECIAL;
import org.apache.bcel.generic.INVOKEVIRTUAL;
import org.apache.bcel.generic.InstructionHandle;
import org.apache.bcel.generic.InstructionList;
import org.apache.bcel.generic.MethodGen;
import org.apache.bcel.generic.PUSH;

/**
 * Read class file(s) and patch all of its methods, so that they print
 * "hello" and their name and signature before doing anything else.
 *
 * @version $Id$
 */
public final class helloify implements Constants {

    private static String class_name;
    private static ConstantPoolGen cp;
    private static int out;     // reference to System.out
    private static int println; // reference to PrintStream.println

    public static void main(String[] argv) throws Exception {
        for (String arg : argv) {
            if (arg.endsWith(".class")) {
                JavaClass java_class = new ClassParser(arg).parse();
                ConstantPool constants = java_class.getConstantPool();
                String file_name = arg.substring(0, arg.length() - 6) + "_hello.class";
                cp = new ConstantPoolGen(constants);

                helloifyClassName(java_class);

                out = cp.addFieldref("java.lang.System", "out", "Ljava/io/PrintStream;");
                println = cp.addMethodref("java.io.PrintStream", "println", "(Ljava/lang/String;)V");
                // Patch all methods.
                Method[] methods = java_class.getMethods();

                for (int j = 0; j < methods.length; j++) {
                    methods[j] = helloifyMethod(methods[j]);
                }

                // Finally dump it back to a file.
                java_class.setConstantPool(cp.getFinalConstantPool());
                java_class.dump(file_name);
            }
        }
    }

    /**
     * Change class name to <old_name>_hello
     */
    private static void helloifyClassName(JavaClass java_class) {
        class_name = java_class.getClassName() + "_hello";
        int index = java_class.getClassNameIndex();

        index = ((ConstantClass) cp.getConstant(index)).getNameIndex();
        cp.setConstant(index, new ConstantUtf8(class_name.replace('.', '/')));
    }

    /**
     * Patch a method.
     */
    private static Method helloifyMethod(Method m) {
        Code code = m.getCode();
        int flags = m.getAccessFlags();
        String name = m.getName();

        // Sanity check
        if (m.isNative() || m.isAbstract() || (code == null)) {
            return m;
        }
    
        // Create instruction list to be inserted at method start.
        String mesg = "Hello from " + Utility.methodSignatureToString(m.getSignature(),
                name,
                Utility.accessToString(flags));
        InstructionList patch = new InstructionList();
        patch.append(new GETSTATIC(out));
        patch.append(new PUSH(cp, mesg));
        patch.append(new INVOKEVIRTUAL(println));

        MethodGen mg = new MethodGen(m, class_name, cp);
        InstructionList il = mg.getInstructionList();
        InstructionHandle[] ihs = il.getInstructionHandles();

        if (name.equals("<init>")) { // First let the super or other constructor be called
            for (int j = 1; j < ihs.length; j++) {
                if (ihs[j].getInstruction() instanceof INVOKESPECIAL) {
                    il.append(ihs[j], patch); // Should check: method name == "<init>"
                    break;
                }
            }
        } else {
            il.insert(ihs[0], patch);
        }

        // Stack size must be at least 2, since the println method takes 2 argument.
        if (code.getMaxStack() < 2) {
            mg.setMaxStack(2);
        }

        m = mg.getMethod();

        il.dispose(); // Reuse instruction handles

        return m;
    }
}
