/*
 * Copyright (c) 2008, 2009, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.dyn.anon;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Arrays;
import java.util.HashSet;
import java.util.IdentityHashMap;
import java.util.Map;

import static sun.dyn.anon.ConstantPoolVisitor.*;

/** A class and its patched constant pool.
 *
 *  This class allow to modify (patch) a constant pool
 *  by changing the value of its entry.
 *  Entry are referenced using index that can be get
 *  by parsing the constant pool using
 *  {@link ConstantPoolParser#parse(ConstantPoolVisitor)}.
 *
 * @see ConstantPoolVisitor
 * @see ConstantPoolParser#createPatch()
 */
public class ConstantPoolPatch {
    final ConstantPoolParser outer;
    final Object[] patchArray;

    ConstantPoolPatch(ConstantPoolParser outer) {
        this.outer      = outer;
        this.patchArray = new Object[outer.getLength()];
    }

    /** Create a {@link ConstantPoolParser} and
     *  a {@link ConstantPoolPatch} in one step.
     *  Equivalent to {@code new ConstantPoolParser(classFile).createPatch()}.
     *
     * @param classFile an array of bytes containing a class.
     * @see #ConstantPoolParser(Class)
     */
    public ConstantPoolPatch(byte[] classFile) throws InvalidConstantPoolFormatException {
        this(new ConstantPoolParser(classFile));
    }

    /** Create a {@link ConstantPoolParser} and
     *  a {@link ConstantPoolPatch} in one step.
     *  Equivalent to {@code new ConstantPoolParser(templateClass).createPatch()}.
     *
     * @param templateClass the class to parse.
     * @see #ConstantPoolParser(Class)
     */
    public ConstantPoolPatch(Class<?> templateClass) throws IOException, InvalidConstantPoolFormatException {
        this(new ConstantPoolParser(templateClass));
    }


    /** Creates a patch from an existing patch.
     *  All changes are copied from that patch.
     * @param patch a patch
     *
     * @see ConstantPoolParser#createPatch()
     */
    public ConstantPoolPatch(ConstantPoolPatch patch) {
        outer      = patch.outer;
        patchArray = patch.patchArray.clone();
    }

    /** Which parser built this patch? */
    public ConstantPoolParser getParser() {
        return outer;
    }

    /** Report the tag at the given index in the constant pool. */
    public byte getTag(int index) {
        return outer.getTag(index);
    }

    /** Report the current patch at the given index of the constant pool.
     *  Null means no patch will be made.
     *  To observe the unpatched entry at the given index, use
     *  {@link #getParser()}{@code .}@link ConstantPoolParser#parse(ConstantPoolVisitor)}
     */
    public Object getPatch(int index) {
        Object value = patchArray[index];
        if (value == null)  return null;
        switch (getTag(index)) {
        case CONSTANT_Fieldref:
        case CONSTANT_Methodref:
        case CONSTANT_InterfaceMethodref:
            if (value instanceof String)
                value = stripSemis(2, (String) value);
            break;
        case CONSTANT_NameAndType:
            if (value instanceof String)
                value = stripSemis(1, (String) value);
            break;
        }
        return value;
    }

    /** Clear all patches. */
    public void clear() {
        Arrays.fill(patchArray, null);
    }

    /** Clear one patch. */
    public void clear(int index) {
        patchArray[index] = null;
    }

    /** Produce the patches as an array. */
    public Object[] getPatches() {
        return patchArray.clone();
    }

    /** Produce the original constant pool as an array. */
    public Object[] getOriginalCP() throws InvalidConstantPoolFormatException {
        return getOriginalCP(0, patchArray.length, -1);
    }

    /** Walk the constant pool, applying patches using the given map.
     *
     * @param utf8Map Utf8 strings to modify, if encountered
     * @param classMap Classes (or their names) to modify, if encountered
     * @param valueMap Constant values to modify, if encountered
     * @param deleteUsedEntries if true, delete map entries that are used
     */
    public void putPatches(final Map<String,String> utf8Map,
                           final Map<String,Object> classMap,
                           final Map<Object,Object> valueMap,
                           boolean deleteUsedEntries) throws InvalidConstantPoolFormatException {
        final HashSet<String> usedUtf8Keys;
        final HashSet<String> usedClassKeys;
        final HashSet<Object> usedValueKeys;
        if (deleteUsedEntries) {
            usedUtf8Keys  = (utf8Map  == null) ? null : new HashSet<String>();
            usedClassKeys = (classMap == null) ? null : new HashSet<String>();
            usedValueKeys = (valueMap == null) ? null : new HashSet<Object>();
        } else {
            usedUtf8Keys = null;
            usedClassKeys = null;
            usedValueKeys = null;
        }

        outer.parse(new ConstantPoolVisitor() {

            @Override
            public void visitUTF8(int index, byte tag, String utf8) {
                putUTF8(index, utf8Map.get(utf8));
                if (usedUtf8Keys != null)  usedUtf8Keys.add(utf8);
            }

            @Override
            public void visitConstantValue(int index, byte tag, Object value) {
                putConstantValue(index, tag, valueMap.get(value));
                if (usedValueKeys != null)  usedValueKeys.add(value);
            }

            @Override
            public void visitConstantString(int index, byte tag, String name, int nameIndex) {
                if (tag == CONSTANT_Class) {
                    putConstantValue(index, tag, classMap.get(name));
                    if (usedClassKeys != null)  usedClassKeys.add(name);
                } else {
                    assert(tag == CONSTANT_String);
                    visitConstantValue(index, tag, name);
                }
            }
        });
        if (usedUtf8Keys != null)   utf8Map.keySet().removeAll(usedUtf8Keys);
        if (usedClassKeys != null)  classMap.keySet().removeAll(usedClassKeys);
        if (usedValueKeys != null)  valueMap.keySet().removeAll(usedValueKeys);
    }

    Object[] getOriginalCP(final int startIndex,
                           final int endIndex,
                           final int tagMask) throws InvalidConstantPoolFormatException {
        final Object[] cpArray = new Object[endIndex - startIndex];
        outer.parse(new ConstantPoolVisitor() {

            void show(int index, byte tag, Object value) {
                if (index < startIndex || index >= endIndex)  return;
                if (((1 << tag) & tagMask) == 0)  return;
                cpArray[index - startIndex] = value;
            }

            @Override
            public void visitUTF8(int index, byte tag, String utf8) {
                show(index, tag, utf8);
            }

            @Override
            public void visitConstantValue(int index, byte tag, Object value) {
                assert(tag != CONSTANT_String);
                show(index, tag, value);
            }

            @Override
            public void visitConstantString(int index, byte tag,
                                            String value, int j) {
                show(index, tag, value);
            }

            @Override
            public void visitMemberRef(int index, byte tag,
                    String className, String memberName,
                    String signature,
                    int j, int k) {
                show(index, tag, new String[]{ className, memberName, signature });
            }

            @Override
            public void visitDescriptor(int index, byte tag,
                    String memberName, String signature,
                    int j, int k) {
                show(index, tag, new String[]{ memberName, signature });
            }
        });
        return cpArray;
    }

    /** Write the head (header plus constant pool)
     *  of the patched class file to the indicated stream.
     */
    void writeHead(OutputStream out) throws IOException {
        outer.writePatchedHead(out, patchArray);
    }

    /** Write the tail (everything after the constant pool)
     *  of the patched class file to the indicated stream.
     */
    void writeTail(OutputStream out) throws IOException {
        outer.writeTail(out);
    }

    private void checkConstantTag(byte tag, Object value) {
        if (value == null)
            throw new IllegalArgumentException(
                    "invalid null constant value");
        if (classForTag(tag) != value.getClass())
            throw new IllegalArgumentException(
                    "invalid constant value"
                    + (tag == CONSTANT_None ? ""
                        : " for tag "+tagName(tag))
                    + " of class "+value.getClass());
    }

    private void checkTag(int index, byte putTag) {
        byte tag = outer.tags[index];
        if (tag != putTag)
            throw new IllegalArgumentException(
                "invalid put operation"
                + " for " + tagName(putTag)
                + " at index " + index + " found " + tagName(tag));
    }

    private void checkTagMask(int index, int tagBitMask) {
        byte tag = outer.tags[index];
        int tagBit = ((tag & 0x1F) == tag) ? (1 << tag) : 0;
        if ((tagBit & tagBitMask) == 0)
            throw new IllegalArgumentException(
                "invalid put operation"
                + " at index " + index + " found " + tagName(tag));
    }

    private static void checkMemberName(String memberName) {
        if (memberName.indexOf(';') >= 0)
            throw new IllegalArgumentException("memberName " + memberName + " contains a ';'");
    }

    /** Set the entry of the constant pool indexed by index to
     *  a new string.
     *
     * @param index an index to a constant pool entry containing a
     *        {@link ConstantPoolVisitor#CONSTANT_Utf8} value.
     * @param utf8 a string
     *
     * @see ConstantPoolVisitor#visitUTF8(int, byte, String)
     */
    public void putUTF8(int index, String utf8) {
        if (utf8 == null) { clear(index); return; }
        checkTag(index, CONSTANT_Utf8);
        patchArray[index] = utf8;
    }

    /** Set the entry of the constant pool indexed by index to
     *  a new value, depending on its dynamic type.
     *
     * @param index an index to a constant pool entry containing a
     *        one of the following structures:
     *        {@link ConstantPoolVisitor#CONSTANT_Integer},
     *        {@link ConstantPoolVisitor#CONSTANT_Float},
     *        {@link ConstantPoolVisitor#CONSTANT_Long},
     *        {@link ConstantPoolVisitor#CONSTANT_Double},
     *        {@link ConstantPoolVisitor#CONSTANT_String}, or
     *        {@link ConstantPoolVisitor#CONSTANT_Class}
     * @param value a boxed int, float, long or double; or a string or class object
     * @throws IllegalArgumentException if the type of the constant does not
     *         match the constant pool entry type,
     *         as reported by {@link #getTag(int)}
     *
     * @see #putConstantValue(int, byte, Object)
     * @see ConstantPoolVisitor#visitConstantValue(int, byte, Object)
     * @see ConstantPoolVisitor#visitConstantString(int, byte, String, int)
     */
    public void putConstantValue(int index, Object value) {
        if (value == null) { clear(index); return; }
        byte tag = tagForConstant(value.getClass());
        checkConstantTag(tag, value);
        checkTag(index, tag);
        patchArray[index] = value;
    }

    /** Set the entry of the constant pool indexed by index to
     *  a new value.
     *
     * @param index an index to a constant pool entry matching the given tag
     * @param tag one of the following values:
     *        {@link ConstantPoolVisitor#CONSTANT_Integer},
     *        {@link ConstantPoolVisitor#CONSTANT_Float},
     *        {@link ConstantPoolVisitor#CONSTANT_Long},
     *        {@link ConstantPoolVisitor#CONSTANT_Double},
     *        {@link ConstantPoolVisitor#CONSTANT_String}, or
     *        {@link ConstantPoolVisitor#CONSTANT_Class}
     * @param value a boxed number, string, or class object
     * @throws IllegalArgumentException if the type of the constant does not
     *         match the constant pool entry type, or if a class name contains
     *         '/' or ';'
     *
     * @see #putConstantValue(int, Object)
     * @see ConstantPoolVisitor#visitConstantValue(int, byte, Object)
     * @see ConstantPoolVisitor#visitConstantString(int, byte, String, int)
     */
    public void putConstantValue(int index, byte tag, Object value) {
        if (value == null) { clear(index); return; }
        checkTag(index, tag);
        if (tag == CONSTANT_Class && value instanceof String) {
            checkClassName((String) value);
        } else if (tag == CONSTANT_String) {
            // the JVM accepts any object as a patch for a string
        } else {
            // make sure the incoming value is the right type
            checkConstantTag(tag, value);
        }
        checkTag(index, tag);
        patchArray[index] = value;
    }

    /** Set the entry of the constant pool indexed by index to
     *  a new {@link ConstantPoolVisitor#CONSTANT_NameAndType} value.
     *
     * @param index an index to a constant pool entry containing a
     *        {@link ConstantPoolVisitor#CONSTANT_NameAndType} value.
     * @param memberName a memberName
     * @param signature a signature
     * @throws IllegalArgumentException if memberName contains the character ';'
     *
     * @see ConstantPoolVisitor#visitDescriptor(int, byte, String, String, int, int)
     */
    public void putDescriptor(int index, String memberName, String signature) {
        checkTag(index, CONSTANT_NameAndType);
        checkMemberName(memberName);
        patchArray[index] = addSemis(memberName, signature);
    }

    /** Set the entry of the constant pool indexed by index to
     *  a new {@link ConstantPoolVisitor#CONSTANT_Fieldref},
     *  {@link ConstantPoolVisitor#CONSTANT_Methodref}, or
     *  {@link ConstantPoolVisitor#CONSTANT_InterfaceMethodref} value.
     *
     * @param index an index to a constant pool entry containing a member reference
     * @param className a class name
     * @param memberName a field or method name
     * @param signature a field or method signature
     * @throws IllegalArgumentException if memberName contains the character ';'
     *             or signature is not a correct signature
     *
     * @see ConstantPoolVisitor#visitMemberRef(int, byte, String, String, String, int, int)
     */
    public void putMemberRef(int index, byte tag,
                    String className, String memberName, String signature) {
        checkTagMask(tag, CONSTANT_MemberRef_MASK);
        checkTag(index, tag);
        checkClassName(className);
        checkMemberName(memberName);
        if (signature.startsWith("(") == (tag == CONSTANT_Fieldref))
            throw new IllegalArgumentException("bad signature: "+signature);
        patchArray[index] = addSemis(className, memberName, signature);
    }

    static private final int CONSTANT_MemberRef_MASK =
              CONSTANT_Fieldref
            | CONSTANT_Methodref
            | CONSTANT_InterfaceMethodref;

    private static final Map<Class<?>, Byte> CONSTANT_VALUE_CLASS_TAG
        = new IdentityHashMap<Class<?>, Byte>();
    private static final Class[] CONSTANT_VALUE_CLASS = new Class[16];
    static {
        Object[][] values = {
            {Integer.class, CONSTANT_Integer},
            {Long.class, CONSTANT_Long},
            {Float.class, CONSTANT_Float},
            {Double.class, CONSTANT_Double},
            {String.class, CONSTANT_String},
            {Class.class, CONSTANT_Class}
        };
        for (Object[] value : values) {
            Class<?> cls = (Class<?>)value[0];
            Byte     tag = (Byte) value[1];
            CONSTANT_VALUE_CLASS_TAG.put(cls, tag);
            CONSTANT_VALUE_CLASS[(byte)tag] = cls;
        }
    }

    static Class<?> classForTag(byte tag) {
        if ((tag & 0xFF) >= CONSTANT_VALUE_CLASS.length)
            return null;
        return CONSTANT_VALUE_CLASS[tag];
    }

    static byte tagForConstant(Class<?> cls) {
        Byte tag = CONSTANT_VALUE_CLASS_TAG.get(cls);
        return (tag == null) ? CONSTANT_None : (byte)tag;
    }

    private static void checkClassName(String className) {
        if (className.indexOf('/') >= 0 || className.indexOf(';') >= 0)
            throw new IllegalArgumentException("invalid class name " + className);
    }

    static String addSemis(String name, String... names) {
        StringBuilder buf = new StringBuilder(name.length() * 5);
        buf.append(name);
        for (String name2 : names) {
            buf.append(';').append(name2);
        }
        String res = buf.toString();
        assert(stripSemis(names.length, res)[0].equals(name));
        assert(stripSemis(names.length, res)[1].equals(names[0]));
        assert(names.length == 1 ||
               stripSemis(names.length, res)[2].equals(names[1]));
        return res;
    }

    static String[] stripSemis(int count, String string) {
        String[] res = new String[count+1];
        int pos = 0;
        for (int i = 0; i < count; i++) {
            int pos2 = string.indexOf(';', pos);
            if (pos2 < 0)  pos2 = string.length();  // yuck
            res[i] = string.substring(pos, pos2);
            pos = pos2;
        }
        res[count] = string.substring(pos);
        return res;
    }

    public String toString() {
        StringBuilder buf = new StringBuilder(this.getClass().getName());
        buf.append("{");
        Object[] origCP = null;
        for (int i = 0; i < patchArray.length; i++) {
            if (patchArray[i] == null)  continue;
            if (origCP != null) {
                buf.append(", ");
            } else {
                try {
                    origCP = getOriginalCP();
                } catch (InvalidConstantPoolFormatException ee) {
                    origCP = new Object[0];
                }
            }
            Object orig = (i < origCP.length) ? origCP[i] : "?";
            buf.append(orig).append("=").append(patchArray[i]);
        }
        buf.append("}");
        return buf.toString();
    }
}
