/*
 * Copyright (c) 1997, 2008, 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.
 */


/*
 * The Original Code is HAT. The Initial Developer of the
 * Original Code is Bill Foote, with contributions from others
 * at JavaSoft/Sun.
 */

package com.sun.tools.hat.internal.model;

import com.sun.tools.hat.internal.parser.ReadBuffer;
import java.io.IOException;

/**
 * An array of values, that is, an array of ints, boolean, floats or the like.
 *
 * @author      Bill Foote
 */
public class JavaValueArray extends JavaLazyReadObject
                /*imports*/ implements ArrayTypeCodes {

    private static String arrayTypeName(byte sig) {
        switch (sig) {
            case 'B':
                return "byte[]";
            case 'Z':
                return "boolean[]";
            case 'C':
                return "char[]";
            case 'S':
                return "short[]";
            case 'I':
                return "int[]";
            case 'F':
                return "float[]";
            case 'J':
                return "long[]";
            case 'D':
                return "double[]";
            default:
                throw new RuntimeException("invalid array element sig: " + sig);
        }
    }

    private static int elementSize(byte type) {
        switch (type) {
            case T_BYTE:
            case T_BOOLEAN:
                return 1;
            case T_CHAR:
            case T_SHORT:
                return 2;
            case T_INT:
            case T_FLOAT:
                return 4;
            case T_LONG:
            case T_DOUBLE:
                return 8;
            default:
                throw new RuntimeException("invalid array element type: " + type);
        }
    }

    /*
     * Java primitive array record (HPROF_GC_PRIM_ARRAY_DUMP) looks
     * as below:
     *
     *    object ID
     *    stack trace serial number (int)
     *    length of the instance data (int)
     *    element type (byte)
     *    array data
     */
    protected final int readValueLength() throws IOException {
        JavaClass cl = getClazz();
        ReadBuffer buf = cl.getReadBuffer();
        int idSize = cl.getIdentifierSize();
        long offset = getOffset() + idSize + 4;
        // length of the array
        int len = buf.getInt(offset);
        // typecode of array element type
        byte type = buf.getByte(offset + 4);
        return len * elementSize(type);
    }

    protected final byte[] readValue() throws IOException {
        JavaClass cl = getClazz();
        ReadBuffer buf = cl.getReadBuffer();
        int idSize = cl.getIdentifierSize();
        long offset = getOffset() + idSize + 4;
        // length of the array
        int length = buf.getInt(offset);
        // typecode of array element type
        byte type = buf.getByte(offset + 4);
        if (length == 0) {
            return Snapshot.EMPTY_BYTE_ARRAY;
        } else {
            length *= elementSize(type);
            byte[] res = new byte[length];
            buf.get(offset + 5, res);
            return res;
        }
    }

    // JavaClass set only after resolve.
    private JavaClass clazz;

    // This field contains elementSignature byte and
    // divider to be used to calculate length. Note that
    // length of content byte[] is not same as array length.
    // Actual array length is (byte[].length / divider)
    private int data;

    // First 8 bits of data is used for element signature
    private static final int SIGNATURE_MASK = 0x0FF;

    // Next 8 bits of data is used for length divider
    private static final int LENGTH_DIVIDER_MASK = 0x0FF00;

    // Number of bits to shift to get length divider
    private static final int LENGTH_DIVIDER_SHIFT = 8;

    public JavaValueArray(byte elementSignature, long offset) {
        super(offset);
        this.data = (elementSignature & SIGNATURE_MASK);
    }

    public JavaClass getClazz() {
        return clazz;
    }

    public void visitReferencedObjects(JavaHeapObjectVisitor v) {
        super.visitReferencedObjects(v);
    }

    public void resolve(Snapshot snapshot) {
        if (clazz instanceof JavaClass) {
            return;
        }
        byte elementSig = getElementType();
        clazz = snapshot.findClass(arrayTypeName(elementSig));
        if (clazz == null) {
            clazz = snapshot.getArrayClass("" + ((char) elementSig));
        }
        getClazz().addInstance(this);
        super.resolve(snapshot);
    }

    public int getLength() {
        int divider = (data & LENGTH_DIVIDER_MASK) >>> LENGTH_DIVIDER_SHIFT;
        if (divider == 0) {
            byte elementSignature = getElementType();
            switch (elementSignature) {
            case 'B':
            case 'Z':
                divider = 1;
                break;
            case 'C':
            case 'S':
                divider = 2;
                break;
            case 'I':
            case 'F':
                divider = 4;
                break;
            case 'J':
            case 'D':
                divider = 8;
                break;
            default:
                throw new RuntimeException("unknown primitive type: " +
                                elementSignature);
            }
            data |= (divider << LENGTH_DIVIDER_SHIFT);
        }
        return (getValueLength() / divider);
    }

    public Object getElements() {
        final int len = getLength();
        final byte et = getElementType();
        byte[] data = getValue();
        int index = 0;
        switch (et) {
            case 'Z': {
                boolean[] res = new boolean[len];
                for (int i = 0; i < len; i++) {
                    res[i] = booleanAt(index, data);
                    index++;
                }
                return res;
            }
            case 'B': {
                byte[] res = new byte[len];
                for (int i = 0; i < len; i++) {
                    res[i] = byteAt(index, data);
                    index++;
                }
                return res;
            }
            case 'C': {
                char[] res = new char[len];
                for (int i = 0; i < len; i++) {
                    res[i] = charAt(index, data);
                    index += 2;
                }
                return res;
            }
            case 'S': {
                short[] res = new short[len];
                for (int i = 0; i < len; i++) {
                    res[i] = shortAt(index, data);
                    index += 2;
                }
                return res;
            }
            case 'I': {
                int[] res = new int[len];
                for (int i = 0; i < len; i++) {
                    res[i] = intAt(index, data);
                    index += 4;
                }
                return res;
            }
            case 'J': {
                long[] res = new long[len];
                for (int i = 0; i < len; i++) {
                    res[i] = longAt(index, data);
                    index += 8;
                }
                return res;
            }
            case 'F': {
                float[] res = new float[len];
                for (int i = 0; i < len; i++) {
                    res[i] = floatAt(index, data);
                    index += 4;
                }
                return res;
            }
            case 'D': {
                double[] res = new double[len];
                for (int i = 0; i < len; i++) {
                    res[i] = doubleAt(index, data);
                    index += 8;
                }
                return res;
            }
            default: {
                throw new RuntimeException("unknown primitive type?");
            }
        }
    }

    public byte getElementType() {
        return (byte) (data & SIGNATURE_MASK);
    }

    private void checkIndex(int index) {
        if (index < 0 || index >= getLength()) {
            throw new ArrayIndexOutOfBoundsException(index);
        }
    }

    private void requireType(char type) {
        if (getElementType() != type) {
            throw new RuntimeException("not of type : " + type);
        }
    }

    public boolean getBooleanAt(int index) {
        checkIndex(index);
        requireType('Z');
        return booleanAt(index, getValue());
    }

    public byte getByteAt(int index) {
        checkIndex(index);
        requireType('B');
        return byteAt(index, getValue());
    }

    public char getCharAt(int index) {
        checkIndex(index);
        requireType('C');
        return charAt(index << 1, getValue());
    }

    public short getShortAt(int index) {
        checkIndex(index);
        requireType('S');
        return shortAt(index << 1, getValue());
    }

    public int getIntAt(int index) {
        checkIndex(index);
        requireType('I');
        return intAt(index << 2, getValue());
    }

    public long getLongAt(int index) {
        checkIndex(index);
        requireType('J');
        return longAt(index << 3, getValue());
    }

    public float getFloatAt(int index) {
        checkIndex(index);
        requireType('F');
        return floatAt(index << 2, getValue());
    }

    public double getDoubleAt(int index) {
        checkIndex(index);
        requireType('D');
        return doubleAt(index << 3, getValue());
    }

    public String valueString() {
        return valueString(true);
    }

    public String valueString(boolean bigLimit) {
        // Char arrays deserve special treatment
        StringBuffer result;
        byte[] value = getValue();
        int max = value.length;
        byte elementSignature = getElementType();
        if (elementSignature == 'C')  {
            result = new StringBuffer();
            for (int i = 0; i < value.length; ) {
                char val = charAt(i, value);
                result.append(val);
                i += 2;
            }
        } else {
            int limit = 8;
            if (bigLimit) {
                limit = 1000;
            }
            result = new StringBuffer("{");
            int num = 0;
            for (int i = 0; i < value.length; ) {
                if (num > 0) {
                    result.append(", ");
                }
                if (num >= limit) {
                    result.append("... ");
                    break;
                }
                num++;
                switch (elementSignature) {
                    case 'Z': {
                        boolean val = booleanAt(i, value);
                        if (val) {
                            result.append("true");
                        } else {
                            result.append("false");
                        }
                        i++;
                        break;
                    }
                    case 'B': {
                        int val = 0xFF & byteAt(i, value);
                        result.append("0x" + Integer.toString(val, 16));
                        i++;
                        break;
                    }
                    case 'S': {
                        short val = shortAt(i, value);
                        i += 2;
                        result.append("" + val);
                        break;
                    }
                    case 'I': {
                        int val = intAt(i, value);
                        i += 4;
                        result.append("" + val);
                        break;
                    }
                    case 'J': {         // long
                        long val = longAt(i, value);
                        result.append("" + val);
                        i += 8;
                        break;
                    }
                    case 'F': {
                        float val = floatAt(i, value);
                        result.append("" + val);
                        i += 4;
                        break;
                    }
                    case 'D': {         // double
                        double val = doubleAt(i, value);
                        result.append("" + val);
                        i += 8;
                        break;
                    }
                    default: {
                        throw new RuntimeException("unknown primitive type?");
                    }
                }
            }
            result.append("}");
        }
        return result.toString();
    }

}
