/*
 *
 * 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.
 *
 */
package org.apache.qpid.client.message;

import java.io.EOFException;
import java.nio.ByteBuffer;
import javax.jms.BytesMessage;
import javax.jms.JMSException;
import javax.jms.MessageEOFException;
import javax.jms.MessageFormatException;
import org.apache.qpid.QpidException;
import org.apache.qpid.typedmessage.TypedBytesContentReader;
import org.apache.qpid.typedmessage.TypedBytesContentWriter;
import org.apache.qpid.typedmessage.TypedBytesFormatException;

public class JMSBytesMessage extends AbstractBytesTypedMessage implements BytesMessage
{
    public static final String MIME_TYPE = "application/octet-stream";


    private TypedBytesContentReader _typedBytesContentReader;
    private TypedBytesContentWriter _typedBytesContentWriter;


    public JMSBytesMessage(AMQMessageDelegateFactory delegateFactory)
    {
        super(delegateFactory,false);
        _typedBytesContentWriter = new TypedBytesContentWriter();
    }

    JMSBytesMessage(AMQMessageDelegate delegate, ByteBuffer data) throws QpidException
    {
        super(delegate, data!=null);
        _typedBytesContentReader = new TypedBytesContentReader(data);
    }


    public void reset()
    {
        setReadable(true);

        if(_typedBytesContentReader != null)
        {
            _typedBytesContentReader.reset();
        }
        else if (_typedBytesContentWriter != null)
        {
            _typedBytesContentReader = new TypedBytesContentReader(_typedBytesContentWriter.getData());
        }
    }

    @Override
    public void clearBody() throws JMSException
    {
        super.clearBody();
        _typedBytesContentReader = null;
        _typedBytesContentWriter = new TypedBytesContentWriter();

    }

    protected String getMimeType()
    {
        return MIME_TYPE;
    }

    @Override
    public java.nio.ByteBuffer getData() throws JMSException
    {
        return _typedBytesContentWriter == null ? _typedBytesContentReader.getData() : _typedBytesContentWriter.getData();
    }

    public long getBodyLength() throws JMSException
    {
        checkReadable();
        return _typedBytesContentReader.size();
    }

    public boolean readBoolean() throws JMSException
    {
        checkReadable();
        checkAvailable(1);

        return _typedBytesContentReader.readBooleanImpl();
    }

    private void checkAvailable(final int i) throws MessageEOFException
    {
        try
        {
            _typedBytesContentReader.checkAvailable(1);
        }
        catch (EOFException e)
        {
            throw new MessageEOFException(e.getMessage());
        }
    }

    public byte readByte() throws JMSException
    {
        checkReadable();
        checkAvailable(1);
        return _typedBytesContentReader.readByteImpl();
    }

    public int readUnsignedByte() throws JMSException
    {
        checkReadable();
        checkAvailable(1);
        return _typedBytesContentReader.readByteImpl() & 0xFF;
    }

    public short readShort() throws JMSException
    {
        checkReadable();
        checkAvailable(2);
        return _typedBytesContentReader.readShortImpl();
    }

    public int readUnsignedShort() throws JMSException
    {
        checkReadable();
        checkAvailable(2);
        return _typedBytesContentReader.readShortImpl() & 0xFFFF;
    }

    /**
     * Note that this method reads a unicode character as two bytes from the stream
     *
     * @return the character read from the stream
     * @throws JMSException
     */
    public char readChar() throws JMSException
    {
        checkReadable();
        checkAvailable(2);
        return _typedBytesContentReader.readCharImpl();
    }

    public int readInt() throws JMSException
    {
        checkReadable();
        checkAvailable(4);
        return _typedBytesContentReader.readIntImpl();
    }

    public long readLong() throws JMSException
    {
        checkReadable();
        checkAvailable(8);
        return _typedBytesContentReader.readLongImpl();
    }

    public float readFloat() throws JMSException
    {
        checkReadable();
        checkAvailable(4);
        return _typedBytesContentReader.readFloatImpl();
    }

    public double readDouble() throws JMSException
    {
        checkReadable();
        checkAvailable(8);
        return _typedBytesContentReader.readDoubleImpl();
    }

    public String readUTF() throws JMSException
    {
        checkReadable();
        // we check only for one byte since theoretically the string could be only a
        // single byte when using UTF-8 encoding

        try
        {
            return _typedBytesContentReader.readLengthPrefixedUTF();
        }
        catch (TypedBytesFormatException e)
        {
            throw new MessageFormatException(e.getMessage());
        }
    }

    public int readBytes(byte[] bytes) throws JMSException
    {
        if (bytes == null)
        {
            throw new IllegalArgumentException("byte array must not be null");
        }
        checkReadable();
        int count = (_typedBytesContentReader.remaining() >= bytes.length ? bytes.length : _typedBytesContentReader.remaining());
        if (count == 0)
        {
            return -1;
        }
        else
        {
            _typedBytesContentReader.readRawBytes(bytes, 0, count);
            return count;
        }
    }

    public int readBytes(byte[] bytes, int maxLength) throws JMSException
    {
        if (bytes == null)
        {
            throw new IllegalArgumentException("byte array must not be null");
        }
        if (maxLength > bytes.length)
        {
            throw new IllegalArgumentException("maxLength must be <= bytes.length");
        }
        checkReadable();
        int count = (_typedBytesContentReader.remaining() >= maxLength ? maxLength : _typedBytesContentReader.remaining());
        if (count == 0)
        {
            return -1;
        }
        else
        {
            _typedBytesContentReader.readRawBytes(bytes, 0, count);
            return count;
        }
    }


    public void writeBoolean(boolean b) throws JMSException
    {
        checkWritable();
        _typedBytesContentWriter.writeBooleanImpl(b);
    }

    public void writeByte(byte b) throws JMSException
    {
        checkWritable();
        _typedBytesContentWriter.writeByteImpl(b);
    }

    public void writeShort(short i) throws JMSException
    {
        checkWritable();
        _typedBytesContentWriter.writeShortImpl(i);
    }

    public void writeChar(char c) throws JMSException
    {
        checkWritable();
        _typedBytesContentWriter.writeCharImpl(c);
    }

    public void writeInt(int i) throws JMSException
    {
        checkWritable();
        _typedBytesContentWriter.writeIntImpl(i);
    }

    public void writeLong(long l) throws JMSException
    {
        checkWritable();
        _typedBytesContentWriter.writeLongImpl(l);
    }

    public void writeFloat(float v) throws JMSException
    {
        checkWritable();
        _typedBytesContentWriter.writeFloatImpl(v);
    }

    public void writeDouble(double v) throws JMSException
    {
        checkWritable();
        _typedBytesContentWriter.writeDoubleImpl(v);
    }

    public void writeUTF(String string) throws JMSException
    {
        checkWritable();
        try
        {
            _typedBytesContentWriter.writeLengthPrefixedUTF(string);
        }
        catch (TypedBytesFormatException e)
        {
            throw new MessageFormatException(e.getMessage());
        }
    }

    public void writeBytes(byte[] bytes) throws JMSException
    {
        writeBytes(bytes, 0, bytes.length);
    }

    public void writeBytes(byte[] bytes, int offset, int length) throws JMSException
    {
        checkWritable();
        _typedBytesContentWriter.writeBytesRaw(bytes, offset, length);
    }

    public void writeObject(Object object) throws JMSException
    {
        checkWritable();
        if (object == null)
        {
            throw new NullPointerException("Argument must not be null");
        }
        Class clazz = object.getClass();
        if (clazz == Byte.class)
        {
            writeByte((Byte) object);
        }
        else if (clazz == Boolean.class)
        {
            writeBoolean((Boolean) object);
        }
        else if (clazz == byte[].class)
        {
            writeBytes((byte[]) object);
        }
        else if (clazz == Short.class)
        {
            writeShort((Short) object);
        }
        else if (clazz == Character.class)
        {
            writeChar((Character) object);
        }
        else if (clazz == Integer.class)
        {
            writeInt((Integer) object);
        }
        else if (clazz == Long.class)
        {
            writeLong((Long) object);
        }
        else if (clazz == Float.class)
        {
            writeFloat((Float) object);
        }
        else if (clazz == Double.class)
        {
            writeDouble((Double) object);
        }
        else if (clazz == String.class)
        {
            writeUTF((String) object);
        }
        else
        {
            throw new MessageFormatException("Only primitives plus byte arrays and String are valid types");
        }
    }
}
