/*
 * Copyright (C) 2008 The Android Open Source Project
 *
 * Licensed 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.
 */

package com.android.dx.dex.file;

import com.android.dx.rop.annotation.Annotation;
import com.android.dx.rop.annotation.NameValuePair;
import com.android.dx.rop.cst.Constant;
import com.android.dx.rop.cst.CstAnnotation;
import com.android.dx.rop.cst.CstArray;
import com.android.dx.rop.cst.CstBoolean;
import com.android.dx.rop.cst.CstByte;
import com.android.dx.rop.cst.CstChar;
import com.android.dx.rop.cst.CstDouble;
import com.android.dx.rop.cst.CstEnumRef;
import com.android.dx.rop.cst.CstFieldRef;
import com.android.dx.rop.cst.CstFloat;
import com.android.dx.rop.cst.CstInteger;
import com.android.dx.rop.cst.CstKnownNull;
import com.android.dx.rop.cst.CstLiteralBits;
import com.android.dx.rop.cst.CstLong;
import com.android.dx.rop.cst.CstMethodRef;
import com.android.dx.rop.cst.CstShort;
import com.android.dx.rop.cst.CstString;
import com.android.dx.rop.cst.CstType;
import com.android.dx.util.AnnotatedOutput;
import com.android.dx.util.Hex;
import java.util.Collection;

/**
 * Handler for writing out {@code encoded_values} and parts
 * thereof.
 */
public final class ValueEncoder {
    /** annotation value type constant: {@code byte} */
    private static final int VALUE_BYTE = 0x00;

    /** annotation value type constant: {@code short} */
    private static final int VALUE_SHORT = 0x02;

    /** annotation value type constant: {@code char} */
    private static final int VALUE_CHAR = 0x03;

    /** annotation value type constant: {@code int} */
    private static final int VALUE_INT = 0x04;

    /** annotation value type constant: {@code long} */
    private static final int VALUE_LONG = 0x06;

    /** annotation value type constant: {@code float} */
    private static final int VALUE_FLOAT = 0x10;

    /** annotation value type constant: {@code double} */
    private static final int VALUE_DOUBLE = 0x11;

    /** annotation value type constant: {@code string} */
    private static final int VALUE_STRING = 0x17;

    /** annotation value type constant: {@code type} */
    private static final int VALUE_TYPE = 0x18;

    /** annotation value type constant: {@code field} */
    private static final int VALUE_FIELD = 0x19;

    /** annotation value type constant: {@code method} */
    private static final int VALUE_METHOD = 0x1a;

    /** annotation value type constant: {@code enum} */
    private static final int VALUE_ENUM = 0x1b;

    /** annotation value type constant: {@code array} */
    private static final int VALUE_ARRAY = 0x1c;

    /** annotation value type constant: {@code annotation} */
    private static final int VALUE_ANNOTATION = 0x1d;

    /** annotation value type constant: {@code null} */
    private static final int VALUE_NULL = 0x1e;

    /** annotation value type constant: {@code boolean} */
    private static final int VALUE_BOOLEAN = 0x1f;

    /** {@code non-null;} file being written */
    private final DexFile file;

    /** {@code non-null;} output stream to write to */
    private final AnnotatedOutput out;

    /**
     * Construct an instance.
     *
     * @param file {@code non-null;} file being written
     * @param out {@code non-null;} output stream to write to
     */
    public ValueEncoder(DexFile file, AnnotatedOutput out) {
        if (file == null) {
            throw new NullPointerException("file == null");
        }

        if (out == null) {
            throw new NullPointerException("out == null");
        }

        this.file = file;
        this.out = out;
    }

    /**
     * Writes out the encoded form of the given constant.
     *
     * @param cst {@code non-null;} the constant to write
     */
    public void writeConstant(Constant cst) {
        int type = constantToValueType(cst);
        int arg;

        switch (type) {
            case VALUE_BYTE:
            case VALUE_SHORT:
            case VALUE_INT:
            case VALUE_LONG: {
                long value = ((CstLiteralBits) cst).getLongBits();
                writeSignedIntegralValue(type, value);
                break;
            }
            case VALUE_CHAR: {
                long value = ((CstLiteralBits) cst).getLongBits();
                writeUnsignedIntegralValue(type, value);
                break;
            }
            case VALUE_FLOAT: {
                // Shift value left 32 so that right-zero-extension works.
                long value = ((CstFloat) cst).getLongBits() << 32;
                writeRightZeroExtendedValue(type, value);
                break;
            }
            case VALUE_DOUBLE: {
                long value = ((CstDouble) cst).getLongBits();
                writeRightZeroExtendedValue(type, value);
                break;
            }
            case VALUE_STRING: {
                int index = file.getStringIds().indexOf((CstString) cst);
                writeUnsignedIntegralValue(type, (long) index);
                break;
            }
            case VALUE_TYPE: {
                int index = file.getTypeIds().indexOf((CstType) cst);
                writeUnsignedIntegralValue(type, (long) index);
                break;
            }
            case VALUE_FIELD: {
                int index = file.getFieldIds().indexOf((CstFieldRef) cst);
                writeUnsignedIntegralValue(type, (long) index);
                break;
            }
            case VALUE_METHOD: {
                int index = file.getMethodIds().indexOf((CstMethodRef) cst);
                writeUnsignedIntegralValue(type, (long) index);
                break;
            }
            case VALUE_ENUM: {
                CstFieldRef fieldRef = ((CstEnumRef) cst).getFieldRef();
                int index = file.getFieldIds().indexOf(fieldRef);
                writeUnsignedIntegralValue(type, (long) index);
                break;
            }
            case VALUE_ARRAY: {
                out.writeByte(type);
                writeArray((CstArray) cst, false);
                break;
            }
            case VALUE_ANNOTATION: {
                out.writeByte(type);
                writeAnnotation(((CstAnnotation) cst).getAnnotation(),
                        false);
                break;
            }
            case VALUE_NULL: {
                out.writeByte(type);
                break;
            }
            case VALUE_BOOLEAN: {
                int value = ((CstBoolean) cst).getIntBits();
                out.writeByte(type | (value << 5));
                break;
            }
            default: {
                throw new RuntimeException("Shouldn't happen");
            }
        }
    }

    /**
     * Gets the value type for the given constant.
     *
     * @param cst {@code non-null;} the constant
     * @return the value type; one of the {@code VALUE_*} constants
     * defined by this class
     */
    private static int constantToValueType(Constant cst) {
        /*
         * TODO: Constant should probable have an associated enum, so this
         * can be a switch().
         */
        if (cst instanceof CstByte) {
            return VALUE_BYTE;
        } else if (cst instanceof CstShort) {
            return VALUE_SHORT;
        } else if (cst instanceof CstChar) {
            return VALUE_CHAR;
        } else if (cst instanceof CstInteger) {
            return VALUE_INT;
        } else if (cst instanceof CstLong) {
            return VALUE_LONG;
        } else if (cst instanceof CstFloat) {
            return VALUE_FLOAT;
        } else if (cst instanceof CstDouble) {
            return VALUE_DOUBLE;
        } else if (cst instanceof CstString) {
            return VALUE_STRING;
        } else if (cst instanceof CstType) {
            return VALUE_TYPE;
        } else if (cst instanceof CstFieldRef) {
            return VALUE_FIELD;
        } else if (cst instanceof CstMethodRef) {
            return VALUE_METHOD;
        } else if (cst instanceof CstEnumRef) {
            return VALUE_ENUM;
        } else if (cst instanceof CstArray) {
            return VALUE_ARRAY;
        } else if (cst instanceof CstAnnotation) {
            return VALUE_ANNOTATION;
        } else if (cst instanceof CstKnownNull) {
            return VALUE_NULL;
        } else if (cst instanceof CstBoolean) {
            return VALUE_BOOLEAN;
        } else {
            throw new RuntimeException("Shouldn't happen");
        }
    }

    /**
     * Writes out the encoded form of the given array, that is, as
     * an {@code encoded_array} and not including a
     * {@code value_type} prefix. If the output stream keeps
     * (debugging) annotations and {@code topLevel} is
     * {@code true}, then this method will write (debugging)
     * annotations.
     *
     * @param array {@code non-null;} array instance to write
     * @param topLevel {@code true} iff the given annotation is the
     * top-level annotation or {@code false} if it is a sub-annotation
     * of some other annotation
     */
    public void writeArray(CstArray array, boolean topLevel) {
        boolean annotates = topLevel && out.annotates();
        CstArray.List list = ((CstArray) array).getList();
        int size = list.size();

        if (annotates) {
            out.annotate("  size: " + Hex.u4(size));
        }

        out.writeUleb128(size);

        for (int i = 0; i < size; i++) {
            Constant cst = list.get(i);
            if (annotates) {
                out.annotate("  [" + Integer.toHexString(i) + "] " +
                        constantToHuman(cst));
            }
            writeConstant(cst);
        }

        if (annotates) {
            out.endAnnotation();
        }
    }

    /**
     * Writes out the encoded form of the given annotation, that is,
     * as an {@code encoded_annotation} and not including a
     * {@code value_type} prefix. If the output stream keeps
     * (debugging) annotations and {@code topLevel} is
     * {@code true}, then this method will write (debugging)
     * annotations.
     *
     * @param annotation {@code non-null;} annotation instance to write
     * @param topLevel {@code true} iff the given annotation is the
     * top-level annotation or {@code false} if it is a sub-annotation
     * of some other annotation
     */
    public void writeAnnotation(Annotation annotation, boolean topLevel) {
        boolean annotates = topLevel && out.annotates();
        StringIdsSection stringIds = file.getStringIds();
        TypeIdsSection typeIds = file.getTypeIds();

        CstType type = annotation.getType();
        int typeIdx = typeIds.indexOf(type);

        if (annotates) {
            out.annotate("  type_idx: " + Hex.u4(typeIdx) + " // " +
                    type.toHuman());
        }

        out.writeUleb128(typeIds.indexOf(annotation.getType()));

        Collection<NameValuePair> pairs = annotation.getNameValuePairs();
        int size = pairs.size();

        if (annotates) {
            out.annotate("  size: " + Hex.u4(size));
        }

        out.writeUleb128(size);

        int at = 0;
        for (NameValuePair pair : pairs) {
            CstString name = pair.getName();
            int nameIdx = stringIds.indexOf(name);
            Constant value = pair.getValue();

            if (annotates) {
                out.annotate(0, "  elements[" + at + "]:");
                at++;
                out.annotate("    name_idx: " + Hex.u4(nameIdx) + " // " +
                        name.toHuman());
            }

            out.writeUleb128(nameIdx);

            if (annotates) {
                out.annotate("    value: " + constantToHuman(value));
            }

            writeConstant(value);
        }

        if (annotates) {
            out.endAnnotation();
        }
    }

    /**
     * Gets the colloquial type name and human form of the type of the
     * given constant, when used as an encoded value.
     *
     * @param cst {@code non-null;} the constant
     * @return {@code non-null;} its type name and human form
     */
    public static String constantToHuman(Constant cst) {
        int type = constantToValueType(cst);

        if (type == VALUE_NULL) {
            return "null";
        }

        StringBuilder sb = new StringBuilder();

        sb.append(cst.typeName());
        sb.append(' ');
        sb.append(cst.toHuman());

        return sb.toString();
    }

    /**
     * Helper for {@link #writeConstant}, which writes out the value
     * for any signed integral type.
     *
     * @param type the type constant
     * @param value {@code long} bits of the value
     */
    private void writeSignedIntegralValue(int type, long value) {
        /*
         * Figure out how many bits are needed to represent the value,
         * including a sign bit: The bit count is subtracted from 65
         * and not 64 to account for the sign bit. The xor operation
         * has the effect of leaving non-negative values alone and
         * unary complementing negative values (so that a leading zero
         * count always returns a useful number for our present
         * purpose).
         */
        int requiredBits =
            65 - Long.numberOfLeadingZeros(value ^ (value >> 63));

        // Round up the requiredBits to a number of bytes.
        int requiredBytes = (requiredBits + 0x07) >> 3;

        /*
         * Write the header byte, which includes the type and
         * requiredBytes - 1.
         */
        out.writeByte(type | ((requiredBytes - 1) << 5));

        // Write the value, per se.
        while (requiredBytes > 0) {
            out.writeByte((byte) value);
            value >>= 8;
            requiredBytes--;
        }
    }

    /**
     * Helper for {@link #writeConstant}, which writes out the value
     * for any unsigned integral type.
     *
     * @param type the type constant
     * @param value {@code long} bits of the value
     */
    private void writeUnsignedIntegralValue(int type, long value) {
        // Figure out how many bits are needed to represent the value.
        int requiredBits = 64 - Long.numberOfLeadingZeros(value);
        if (requiredBits == 0) {
            requiredBits = 1;
        }

        // Round up the requiredBits to a number of bytes.
        int requiredBytes = (requiredBits + 0x07) >> 3;

        /*
         * Write the header byte, which includes the type and
         * requiredBytes - 1.
         */
        out.writeByte(type | ((requiredBytes - 1) << 5));

        // Write the value, per se.
        while (requiredBytes > 0) {
            out.writeByte((byte) value);
            value >>= 8;
            requiredBytes--;
        }
    }

    /**
     * Helper for {@link #writeConstant}, which writes out a
     * right-zero-extended value.
     *
     * @param type the type constant
     * @param value {@code long} bits of the value
     */
    private void writeRightZeroExtendedValue(int type, long value) {
        // Figure out how many bits are needed to represent the value.
        int requiredBits = 64 - Long.numberOfTrailingZeros(value);
        if (requiredBits == 0) {
            requiredBits = 1;
        }

        // Round up the requiredBits to a number of bytes.
        int requiredBytes = (requiredBits + 0x07) >> 3;

        // Scootch the first bits to be written down to the low-order bits.
        value >>= 64 - (requiredBytes * 8);

        /*
         * Write the header byte, which includes the type and
         * requiredBytes - 1.
         */
        out.writeByte(type | ((requiredBytes - 1) << 5));

        // Write the value, per se.
        while (requiredBytes > 0) {
            out.writeByte((byte) value);
            value >>= 8;
            requiredBytes--;
        }
    }


    /**
     * Helper for {@code addContents()} methods, which adds
     * contents for a particular {@link Annotation}, calling itself
     * recursively should it encounter a nested annotation.
     *
     * @param file {@code non-null;} the file to add to
     * @param annotation {@code non-null;} the annotation to add contents for
     */
    public static void addContents(DexFile file, Annotation annotation) {
        TypeIdsSection typeIds = file.getTypeIds();
        StringIdsSection stringIds = file.getStringIds();

        typeIds.intern(annotation.getType());

        for (NameValuePair pair : annotation.getNameValuePairs()) {
            stringIds.intern(pair.getName());
            addContents(file, pair.getValue());
        }
    }

    /**
     * Helper for {@code addContents()} methods, which adds
     * contents for a particular constant, calling itself recursively
     * should it encounter a {@link CstArray} and calling {@link
     * #addContents(DexFile,Annotation)} recursively should it
     * encounter a {@link CstAnnotation}.
     *
     * @param file {@code non-null;} the file to add to
     * @param cst {@code non-null;} the constant to add contents for
     */
    public static void addContents(DexFile file, Constant cst) {
        if (cst instanceof CstAnnotation) {
            addContents(file, ((CstAnnotation) cst).getAnnotation());
        } else if (cst instanceof CstArray) {
            CstArray.List list = ((CstArray) cst).getList();
            int size = list.size();
            for (int i = 0; i < size; i++) {
                addContents(file, list.get(i));
            }
        } else {
            file.internIfAppropriate(cst);
        }
    }
}
