/*
 * Copyright 1998-2005 Sun Microsystems, Inc.  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.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

package com.sun.tools.jdi;

import com.sun.jdi.*;
import java.util.*;
import java.io.ByteArrayOutputStream;

class PacketStream {
    final VirtualMachineImpl vm;
    private int inCursor = 0;
    final Packet pkt;
    private ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
    private boolean isCommitted = false;

    PacketStream(VirtualMachineImpl vm, int cmdSet, int cmd) {
        this.vm = vm;
        this.pkt = new Packet();
        pkt.cmdSet = (short)cmdSet;
        pkt.cmd = (short)cmd;
    }

    PacketStream(VirtualMachineImpl vm, Packet pkt) {
        this.vm = vm;
        this.pkt = pkt;
        this.isCommitted = true; /* read only stream */
    }

    int id() {
        return pkt.id;
    }

    void send() {
        if (!isCommitted) {
            pkt.data = dataStream.toByteArray();
            vm.sendToTarget(pkt);
            isCommitted = true;
        }
    }

    void waitForReply() throws JDWPException {
        if (!isCommitted) {
            throw new InternalException("waitForReply without send");
        }

        vm.waitForTargetReply(pkt);

        if (pkt.errorCode != Packet.ReplyNoError) {
            throw new JDWPException(pkt.errorCode);
        }
    }

    void writeBoolean(boolean data) {
        if(data) {
            dataStream.write( 1 );
        } else {
            dataStream.write( 0 );
        }
    }

    void writeByte(byte data) {
        dataStream.write( data );
    }

    void writeChar(char data) {
        dataStream.write( (byte)((data >>> 8) & 0xFF) );
        dataStream.write( (byte)((data >>> 0) & 0xFF) );
    }

    void writeShort(short data) {
        dataStream.write( (byte)((data >>> 8) & 0xFF) );
        dataStream.write( (byte)((data >>> 0) & 0xFF) );
    }

    void writeInt(int data) {
        dataStream.write( (byte)((data >>> 24) & 0xFF) );
        dataStream.write( (byte)((data >>> 16) & 0xFF) );
        dataStream.write( (byte)((data >>> 8) & 0xFF) );
        dataStream.write( (byte)((data >>> 0) & 0xFF) );
    }

    void writeLong(long data) {
        dataStream.write( (byte)((data >>> 56) & 0xFF) );
        dataStream.write( (byte)((data >>> 48) & 0xFF) );
        dataStream.write( (byte)((data >>> 40) & 0xFF) );
        dataStream.write( (byte)((data >>> 32) & 0xFF) );

        dataStream.write( (byte)((data >>> 24) & 0xFF) );
        dataStream.write( (byte)((data >>> 16) & 0xFF) );
        dataStream.write( (byte)((data >>> 8) & 0xFF) );
        dataStream.write( (byte)((data >>> 0) & 0xFF) );
    }

    void writeFloat(float data) {
        writeInt(Float.floatToIntBits(data));
    }

    void writeDouble(double data) {
        writeLong(Double.doubleToLongBits(data));
    }

    void writeID(int size, long data) {
        switch (size) {
            case 8:
                writeLong(data);
                break;
            case 4:
                writeInt((int)data);
                break;
            case 2:
                writeShort((short)data);
                break;
            default:
                throw new UnsupportedOperationException("JDWP: ID size not supported: " + size);
        }
    }

    void writeNullObjectRef() {
        writeObjectRef(0);
    }

    void writeObjectRef(long data) {
        writeID(vm.sizeofObjectRef, data);
    }

    void writeClassRef(long data) {
        writeID(vm.sizeofClassRef, data);
    }

    void writeMethodRef(long data) {
        writeID(vm.sizeofMethodRef, data);
    }

    void writeFieldRef(long data) {
        writeID(vm.sizeofFieldRef, data);
    }

    void writeFrameRef(long data) {
        writeID(vm.sizeofFrameRef, data);
    }

    void writeByteArray(byte[] data) {
        dataStream.write(data, 0, data.length);
    }

    void writeString(String string) {
        try {
            byte[] stringBytes = string.getBytes("UTF8");
            writeInt(stringBytes.length);
            writeByteArray(stringBytes);
        } catch (java.io.UnsupportedEncodingException e) {
            throw new InternalException("Cannot convert string to UTF8 bytes");
        }
    }

    void writeLocation(Location location) {
        ReferenceTypeImpl refType = (ReferenceTypeImpl)location.declaringType();
        byte tag;
        if (refType instanceof ClassType) {
            tag = JDWP.TypeTag.CLASS;
        } else if (refType instanceof InterfaceType) {
            // It's possible to have executable code in an interface
            tag = JDWP.TypeTag.INTERFACE;
        } else {
            throw new InternalException("Invalid Location");
        }
        writeByte(tag);
        writeClassRef(refType.ref());
        writeMethodRef(((MethodImpl)location.method()).ref());
        writeLong(location.codeIndex());
    }

    void writeValue(Value val) {
        try {
            writeValueChecked(val);
        } catch (InvalidTypeException exc) {  // should never happen
            throw new RuntimeException(
                "Internal error: Invalid Tag/Type pair");
        }
    }

    void writeValueChecked(Value val) throws InvalidTypeException {
        writeByte(ValueImpl.typeValueKey(val));
        writeUntaggedValue(val);
    }

    void writeUntaggedValue(Value val) {
        try {
            writeUntaggedValueChecked(val);
        } catch (InvalidTypeException exc) {  // should never happen
            throw new RuntimeException(
                "Internal error: Invalid Tag/Type pair");
        }
    }

    void writeUntaggedValueChecked(Value val) throws InvalidTypeException {
        byte tag = ValueImpl.typeValueKey(val);
        if (isObjectTag(tag)) {
            if (val == null) {
                 writeObjectRef(0);
            } else {
                if (!(val instanceof ObjectReference)) {
                    throw new InvalidTypeException();
                }
                writeObjectRef(((ObjectReferenceImpl)val).ref());
            }
        } else {
            switch (tag) {
                case JDWP.Tag.BYTE:
                    if(!(val instanceof ByteValue))
                        throw new InvalidTypeException();

                    writeByte(((PrimitiveValue)val).byteValue());
                    break;

                case JDWP.Tag.CHAR:
                    if(!(val instanceof CharValue))
                        throw new InvalidTypeException();

                    writeChar(((PrimitiveValue)val).charValue());
                    break;

                case JDWP.Tag.FLOAT:
                    if(!(val instanceof FloatValue))
                        throw new InvalidTypeException();

                    writeFloat(((PrimitiveValue)val).floatValue());
                    break;

                case JDWP.Tag.DOUBLE:
                    if(!(val instanceof DoubleValue))
                        throw new InvalidTypeException();

                    writeDouble(((PrimitiveValue)val).doubleValue());
                    break;

                case JDWP.Tag.INT:
                    if(!(val instanceof IntegerValue))
                        throw new InvalidTypeException();

                    writeInt(((PrimitiveValue)val).intValue());
                    break;

                case JDWP.Tag.LONG:
                    if(!(val instanceof LongValue))
                        throw new InvalidTypeException();

                    writeLong(((PrimitiveValue)val).longValue());
                    break;

                case JDWP.Tag.SHORT:
                    if(!(val instanceof ShortValue))
                        throw new InvalidTypeException();

                    writeShort(((PrimitiveValue)val).shortValue());
                    break;

                case JDWP.Tag.BOOLEAN:
                    if(!(val instanceof BooleanValue))
                        throw new InvalidTypeException();

                    writeBoolean(((PrimitiveValue)val).booleanValue());
                    break;
            }
        }
    }



    /**
     * Read byte represented as one bytes.
     */
    byte readByte() {
        byte ret = pkt.data[inCursor];
        inCursor += 1;
        return ret;
    }

    /**
     * Read boolean represented as one byte.
     */
    boolean readBoolean() {
        byte ret = readByte();
        return (ret != 0);
    }

    /**
     * Read char represented as two bytes.
     */
    char readChar() {
        int b1, b2;

        b1 = pkt.data[inCursor++] & 0xff;
        b2 = pkt.data[inCursor++] & 0xff;

        return (char)((b1 << 8) + b2);
    }

    /**
     * Read short represented as two bytes.
     */
    short readShort() {
        int b1, b2;

        b1 = pkt.data[inCursor++] & 0xff;
        b2 = pkt.data[inCursor++] & 0xff;

        return (short)((b1 << 8) + b2);
    }

    /**
     * Read int represented as four bytes.
     */
    int readInt() {
        int b1,b2,b3,b4;

        b1 = pkt.data[inCursor++] & 0xff;
        b2 = pkt.data[inCursor++] & 0xff;
        b3 = pkt.data[inCursor++] & 0xff;
        b4 = pkt.data[inCursor++] & 0xff;

        return ((b1 << 24) + (b2 << 16) + (b3 << 8) + b4);
    }

    /**
     * Read long represented as eight bytes.
     */
    long readLong() {
        long b1,b2,b3,b4;
        long b5,b6,b7,b8;

        b1 = pkt.data[inCursor++] & 0xff;
        b2 = pkt.data[inCursor++] & 0xff;
        b3 = pkt.data[inCursor++] & 0xff;
        b4 = pkt.data[inCursor++] & 0xff;

        b5 = pkt.data[inCursor++] & 0xff;
        b6 = pkt.data[inCursor++] & 0xff;
        b7 = pkt.data[inCursor++] & 0xff;
        b8 = pkt.data[inCursor++] & 0xff;

        return ((b1 << 56) + (b2 << 48) + (b3 << 40) + (b4 << 32)
                + (b5 << 24) + (b6 << 16) + (b7 << 8) + b8);
    }

    /**
     * Read float represented as four bytes.
     */
    float readFloat() {
        return Float.intBitsToFloat(readInt());
    }

    /**
     * Read double represented as eight bytes.
     */
    double readDouble() {
        return Double.longBitsToDouble(readLong());
    }

    /**
     * Read string represented as four byte length followed by
     * characters of the string.
     */
    String readString() {
        String ret;
        int len = readInt();

        try {
            ret = new String(pkt.data, inCursor, len, "UTF8");
        } catch(java.io.UnsupportedEncodingException e) {
            System.err.println(e);
            ret = "Conversion error!";
        }
        inCursor += len;
        return ret;
    }

    private long readID(int size) {
        switch (size) {
          case 8:
              return readLong();
          case 4:
              return (long)readInt();
          case 2:
              return (long)readShort();
          default:
              throw new UnsupportedOperationException("JDWP: ID size not supported: " + size);
        }
    }

    /**
     * Read object represented as vm specific byte sequence.
     */
    long readObjectRef() {
        return readID(vm.sizeofObjectRef);
    }

    long readClassRef() {
        return readID(vm.sizeofClassRef);
    }

    ObjectReferenceImpl readTaggedObjectReference() {
        byte typeKey = readByte();
        return vm.objectMirror(readObjectRef(), typeKey);
    }

    ObjectReferenceImpl readObjectReference() {
        return vm.objectMirror(readObjectRef());
    }

    StringReferenceImpl readStringReference() {
        long ref = readObjectRef();
        return vm.stringMirror(ref);
    }

    ArrayReferenceImpl readArrayReference() {
        long ref = readObjectRef();
        return vm.arrayMirror(ref);
    }

    ThreadReferenceImpl readThreadReference() {
        long ref = readObjectRef();
        return vm.threadMirror(ref);
    }

    ThreadGroupReferenceImpl readThreadGroupReference() {
        long ref = readObjectRef();
        return vm.threadGroupMirror(ref);
    }

    ClassLoaderReferenceImpl readClassLoaderReference() {
        long ref = readObjectRef();
        return vm.classLoaderMirror(ref);
    }

    ClassObjectReferenceImpl readClassObjectReference() {
        long ref = readObjectRef();
        return vm.classObjectMirror(ref);
    }

    ReferenceTypeImpl readReferenceType() {
        byte tag = readByte();
        long ref = readObjectRef();
        return vm.referenceType(ref, tag);
    }

    /**
     * Read method reference represented as vm specific byte sequence.
     */
    long readMethodRef() {
        return readID(vm.sizeofMethodRef);
    }

    /**
     * Read field reference represented as vm specific byte sequence.
     */
    long readFieldRef() {
        return readID(vm.sizeofFieldRef);
    }

    /**
     * Read field represented as vm specific byte sequence.
     */
    Field readField() {
        ReferenceTypeImpl refType = (ReferenceTypeImpl)readReferenceType();
        long fieldRef = readFieldRef();
        return refType.getFieldMirror(fieldRef);
    }

    /**
     * Read frame represented as vm specific byte sequence.
     */
    long readFrameRef() {
        return readID(vm.sizeofFrameRef);
    }

    /**
     * Read a value, first byte describes type of value to read.
     */
    ValueImpl readValue() {
        byte typeKey = readByte();
        return readUntaggedValue(typeKey);
    }

    ValueImpl readUntaggedValue(byte typeKey) {
        ValueImpl val = null;

        if (isObjectTag(typeKey)) {
            val = vm.objectMirror(readObjectRef(), typeKey);
        } else {
            switch(typeKey) {
                case JDWP.Tag.BYTE:
                    val = new ByteValueImpl(vm, readByte());
                    break;

                case JDWP.Tag.CHAR:
                    val = new CharValueImpl(vm, readChar());
                    break;

                case JDWP.Tag.FLOAT:
                    val = new FloatValueImpl(vm, readFloat());
                    break;

                case JDWP.Tag.DOUBLE:
                    val = new DoubleValueImpl(vm, readDouble());
                    break;

                case JDWP.Tag.INT:
                    val = new IntegerValueImpl(vm, readInt());
                    break;

                case JDWP.Tag.LONG:
                    val = new LongValueImpl(vm, readLong());
                    break;

                case JDWP.Tag.SHORT:
                    val = new ShortValueImpl(vm, readShort());
                    break;

                case JDWP.Tag.BOOLEAN:
                    val = new BooleanValueImpl(vm, readBoolean());
                    break;

                case JDWP.Tag.VOID:
                    val = new VoidValueImpl(vm);
                    break;
            }
        }
        return val;
    }

    /**
     * Read location represented as vm specific byte sequence.
     */
    Location readLocation() {
        byte tag = readByte();
        long classRef = readObjectRef();
        long methodRef = readMethodRef();
        long codeIndex = readLong();
        if (classRef != 0) {
            /* Valid location */
            ReferenceTypeImpl refType = vm.referenceType(classRef, tag);
            return new LocationImpl(vm, refType, methodRef, codeIndex);
        } else {
            /* Null location (example: uncaught exception) */
           return null;
        }
    }

    byte[] readByteArray(int length) {
        byte[] array = new byte[length];
        System.arraycopy(pkt.data, inCursor, array, 0, length);
        inCursor += length;
        return array;
    }

    List<Value> readArrayRegion() {
        byte typeKey = readByte();
        int length = readInt();
        List<Value> list = new ArrayList<Value>(length);
        boolean gettingObjects = isObjectTag(typeKey);
        for (int i = 0; i < length; i++) {
            /*
             * Each object comes back with a type key which might
             * identify a more specific type than the type key we
             * passed in, so we use it in the decodeValue call.
             * (For primitives, we just use the original one)
             */
            if (gettingObjects) {
                typeKey = readByte();
            }
            Value value = readUntaggedValue(typeKey);
            list.add(value);
        }

        return list;
    }

    void writeArrayRegion(List<Value> srcValues) {
        writeInt(srcValues.size());
        for (int i = 0; i < srcValues.size(); i++) {
            Value value = srcValues.get(i);
            writeUntaggedValue(value);
        }
    }

    int skipBytes(int n) {
        inCursor += n;
        return n;
    }

    byte command() {
        return (byte)pkt.cmd;
    }

    static boolean isObjectTag(byte tag) {
        return (tag == JDWP.Tag.OBJECT) ||
               (tag == JDWP.Tag.ARRAY) ||
               (tag == JDWP.Tag.STRING) ||
               (tag == JDWP.Tag.THREAD) ||
               (tag == JDWP.Tag.THREAD_GROUP) ||
               (tag == JDWP.Tag.CLASS_LOADER) ||
               (tag == JDWP.Tag.CLASS_OBJECT);
    }
}
