/*
 *
 * 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.server.protocol.v0_8;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;

import org.apache.qpid.server.bytebuffer.QpidByteBuffer;
import org.apache.qpid.test.utils.QpidTestCase;
import org.junit.Assert;

public class FieldTableTest extends QpidTestCase
{
    /**
     * Test that setting a similar named value replaces any previous value set on that name
     */
    public void testReplacement()
    {
        FieldTable table1 = new FieldTable();
        // Set a boolean value
        table1.setBoolean("value", true);
        // Check length of table is correct (<Value length> + <type> + <Boolean length>)
        int size = EncodingUtils.encodedShortStringLength("value") + 1 + EncodingUtils.encodedBooleanLength();
        Assert.assertEquals(size, table1.getEncodedSize());

        // reset value to an integer
        table1.setInteger("value", Integer.MAX_VALUE);

        // Check the length has changed accordingly   (<Value length> + <type> + <Integer length>)
        size = EncodingUtils.encodedShortStringLength("value") + 1 + EncodingUtils.encodedIntegerLength();
        Assert.assertEquals(size, table1.getEncodedSize());

        // Check boolean value is null
        Assert.assertEquals(null, table1.getBoolean("value"));
        // ... and integer value is good
        Assert.assertEquals((Integer) Integer.MAX_VALUE, table1.getInteger("value"));
    }

    /**
     * Set a boolean and check that we can only get it back as a boolean and a string
     * Check that attempting to lookup a non existent value returns null
     */
    public void testBoolean()
    {
        FieldTable table1 = new FieldTable();
        table1.setBoolean("value", true);
        Assert.assertTrue(table1.propertyExists("value"));

        // Test Getting right value back
        Assert.assertEquals((Boolean) true, table1.getBoolean("value"));

        // Check we don't get anything back for other gets
        Assert.assertEquals(null, table1.getByte("value"));
        Assert.assertEquals(null, table1.getByte("value"));
        Assert.assertEquals(null, table1.getShort("value"));
        Assert.assertEquals(null, table1.getCharacter("value"));
        Assert.assertEquals(null, table1.getDouble("value"));
        Assert.assertEquals(null, table1.getFloat("value"));
        Assert.assertEquals(null, table1.getInteger("value"));
        Assert.assertEquals(null, table1.getLong("value"));
        Assert.assertEquals(null, table1.getBytes("value"));

        // except value as a string
        Assert.assertEquals("true", table1.getString("value"));

        table1.remove("value");

        // Table should now have zero length for encoding
        checkEmpty(table1);

        // Looking up an invalid value returns null
        Assert.assertEquals(null, table1.getBoolean("Rubbish"));
    }

    /**
     * Set a byte and check that we can only get it back as a byte and a string
     * Check that attempting to lookup a non existent value returns null
     */
    public void testByte()
    {
        FieldTable table1 = new FieldTable();
        table1.setByte("value", Byte.MAX_VALUE);
        Assert.assertTrue(table1.propertyExists("value"));

        // Tests lookups we shouldn't get anything back for other gets
        // we should get right value back for this type ....
        Assert.assertEquals(null, table1.getBoolean("value"));
        Assert.assertEquals(Byte.valueOf(Byte.MAX_VALUE), table1.getByte("value"));
        Assert.assertEquals(null, table1.getShort("value"));
        Assert.assertEquals(null, table1.getCharacter("value"));
        Assert.assertEquals(null, table1.getDouble("value"));
        Assert.assertEquals(null, table1.getFloat("value"));
        Assert.assertEquals(null, table1.getInteger("value"));
        Assert.assertEquals(null, table1.getLong("value"));
        Assert.assertEquals(null, table1.getBytes("value"));

        // ... and a the string value of it.
        Assert.assertEquals("" + Byte.MAX_VALUE, table1.getString("value"));

        table1.remove("value");
        // Table should now have zero length for encoding
        checkEmpty(table1);

        // Looking up an invalid value returns null
        Assert.assertEquals(null, table1.getByte("Rubbish"));
    }

    /**
     * Set a short and check that we can only get it back as a short and a string
     * Check that attempting to lookup a non existent value returns null
     */
    public void testShort()
    {
        FieldTable table1 = new FieldTable();
        table1.setShort("value", Short.MAX_VALUE);
        Assert.assertTrue(table1.propertyExists("value"));

        // Tests lookups we shouldn't get anything back for other gets
        // we should get right value back for this type ....
        Assert.assertEquals(null, table1.getBoolean("value"));
        Assert.assertEquals(null, table1.getByte("value"));
        Assert.assertEquals(Short.valueOf(Short.MAX_VALUE), table1.getShort("value"));
        Assert.assertEquals(null, table1.getCharacter("value"));
        Assert.assertEquals(null, table1.getDouble("value"));
        Assert.assertEquals(null, table1.getFloat("value"));
        Assert.assertEquals(null, table1.getInteger("value"));
        Assert.assertEquals(null, table1.getLong("value"));
        Assert.assertEquals(null, table1.getBytes("value"));

        // ... and a the string value of it.
        Assert.assertEquals("" + Short.MAX_VALUE, table1.getString("value"));

        table1.remove("value");
        // Table should now have zero length for encoding
        checkEmpty(table1);

        // Looking up an invalid value returns null
        Assert.assertEquals(null, table1.getShort("Rubbish"));
    }

    /**
     * Set a char and check that we can only get it back as a char
     * Check that attempting to lookup a non existent value returns null
     */
    public void testChar()
    {
        FieldTable table1 = new FieldTable();
        table1.setChar("value", 'c');
        Assert.assertTrue(table1.propertyExists("value"));

        // Tests lookups we shouldn't get anything back for other gets
        // we should get right value back for this type ....
        Assert.assertEquals(null, table1.getBoolean("value"));
        Assert.assertEquals(null, table1.getByte("value"));
        Assert.assertEquals(null, table1.getShort("value"));
        Assert.assertEquals(Character.valueOf('c'), table1.getCharacter("value"));
        Assert.assertEquals(null, table1.getDouble("value"));
        Assert.assertEquals(null, table1.getFloat("value"));
        Assert.assertEquals(null, table1.getInteger("value"));
        Assert.assertEquals(null, table1.getLong("value"));
        Assert.assertEquals(null, table1.getBytes("value"));

        // ... and a the string value of it.
        Assert.assertEquals("c", table1.getString("value"));

        table1.remove("value");

        // Table should now have zero length for encoding
        checkEmpty(table1);

        // Looking up an invalid value returns null
        Assert.assertEquals(null, table1.getCharacter("Rubbish"));
    }

    /**
     * Set a double and check that we can only get it back as a double
     * Check that attempting to lookup a non existent value returns null
     */
    public void testDouble()
    {
        FieldTable table1 = new FieldTable();
        table1.setDouble("value", Double.MAX_VALUE);
        Assert.assertTrue(table1.propertyExists("value"));

        // Tests lookups we shouldn't get anything back for other gets
        // we should get right value back for this type ....
        Assert.assertEquals(null, table1.getBoolean("value"));
        Assert.assertEquals(null, table1.getByte("value"));
        Assert.assertEquals(null, table1.getShort("value"));
        Assert.assertEquals(null, table1.getCharacter("value"));
        Assert.assertEquals(Double.valueOf(Double.MAX_VALUE), table1.getDouble("value"));
        Assert.assertEquals(null, table1.getFloat("value"));
        Assert.assertEquals(null, table1.getInteger("value"));
        Assert.assertEquals(null, table1.getLong("value"));
        Assert.assertEquals(null, table1.getBytes("value"));

        // ... and a the string value of it.
        Assert.assertEquals("" + Double.MAX_VALUE, table1.getString("value"));
        table1.remove("value");
        // but after a removeKey it doesn't
        Assert.assertFalse(table1.containsKey("value"));

        // Table should now have zero length for encoding
        checkEmpty(table1);

        // Looking up an invalid value returns null
        Assert.assertEquals(null, table1.getDouble("Rubbish"));
    }

    /**
     * Set a float and check that we can only get it back as a float
     * Check that attempting to lookup a non existent value returns null
     */
    public void testFloat()
    {
        FieldTable table1 = new FieldTable();
        table1.setFloat("value", Float.MAX_VALUE);
        Assert.assertTrue(table1.propertyExists("value"));

        // Tests lookups we shouldn't get anything back for other gets
        // we should get right value back for this type ....
        Assert.assertEquals(null, table1.getBoolean("value"));
        Assert.assertEquals(null, table1.getByte("value"));
        Assert.assertEquals(null, table1.getShort("value"));
        Assert.assertEquals(null, table1.getCharacter("value"));
        Assert.assertEquals(null, table1.getDouble("value"));
        Assert.assertEquals(Float.valueOf(Float.MAX_VALUE), table1.getFloat("value"));
        Assert.assertEquals(null, table1.getInteger("value"));
        Assert.assertEquals(null, table1.getLong("value"));
        Assert.assertEquals(null, table1.getBytes("value"));

        // ... and a the string value of it.
        Assert.assertEquals("" + Float.MAX_VALUE, table1.getString("value"));

        table1.remove("value");
        // but after a removeKey it doesn't
        Assert.assertFalse(table1.containsKey("value"));

        // Table should now have zero length for encoding
        checkEmpty(table1);

        // Looking up an invalid value returns null
        Assert.assertEquals(null, table1.getFloat("Rubbish"));
    }

    /**
     * Set an int and check that we can only get it back as an int
     * Check that attempting to lookup a non existent value returns null
     */
    public void testInt()
    {
        FieldTable table1 = new FieldTable();
        table1.setInteger("value", Integer.MAX_VALUE);
        Assert.assertTrue(table1.propertyExists("value"));

        // Tets lookups we shouldn't get anything back for other gets
        // we should get right value back for this type ....
        Assert.assertEquals(null, table1.getBoolean("value"));
        Assert.assertEquals(null, table1.getByte("value"));
        Assert.assertEquals(null, table1.getShort("value"));
        Assert.assertEquals(null, table1.getCharacter("value"));
        Assert.assertEquals(null, table1.getDouble("value"));
        Assert.assertEquals(null, table1.getFloat("value"));
        Assert.assertEquals(Integer.valueOf(Integer.MAX_VALUE), table1.getInteger("value"));
        Assert.assertEquals(null, table1.getLong("value"));
        Assert.assertEquals(null, table1.getBytes("value"));

        // ... and a the string value of it.
        Assert.assertEquals("" + Integer.MAX_VALUE, table1.getString("value"));

        table1.remove("value");
        // but after a removeKey it doesn't
        Assert.assertFalse(table1.containsKey("value"));

        // Table should now have zero length for encoding
        checkEmpty(table1);

        // Looking up an invalid value returns null
        Assert.assertEquals(null, table1.getInteger("Rubbish"));
    }

    /**
     * Set a long and check that we can only get it back as a long
     * Check that attempting to lookup a non existent value returns null
     */
    public void testLong()
    {
        FieldTable table1 = new FieldTable();
        table1.setLong("value", Long.MAX_VALUE);
        Assert.assertTrue(table1.propertyExists("value"));

        // Tets lookups we shouldn't get anything back for other gets
        // we should get right value back for this type ....
        Assert.assertEquals(null, table1.getBoolean("value"));
        Assert.assertEquals(null, table1.getByte("value"));
        Assert.assertEquals(null, table1.getShort("value"));
        Assert.assertEquals(null, table1.getCharacter("value"));
        Assert.assertEquals(null, table1.getDouble("value"));
        Assert.assertEquals(null, table1.getFloat("value"));
        Assert.assertEquals(null, table1.getInteger("value"));
        Assert.assertEquals(Long.valueOf(Long.MAX_VALUE), table1.getLong("value"));
        Assert.assertEquals(null, table1.getBytes("value"));

        // ... and a the string value of it.
        Assert.assertEquals("" + Long.MAX_VALUE, table1.getString("value"));

        table1.remove("value");
        // but after a removeKey it doesn't
        Assert.assertFalse(table1.containsKey("value"));

        // Table should now have zero length for encoding
        checkEmpty(table1);

        // Looking up an invalid value returns null
        Assert.assertEquals(null, table1.getLong("Rubbish"));
    }

    /**
     * Set a double and check that we can only get it back as a double
     * Check that attempting to lookup a non existent value returns null
     */
    public void testBytes()
    {
        byte[] bytes = { 99, 98, 97, 96, 95 };

        FieldTable table1 = new FieldTable();
        table1.setBytes("value", bytes);
        Assert.assertTrue(table1.propertyExists("value"));

        // Tets lookups we shouldn't get anything back for other gets
        // we should get right value back for this type ....
        Assert.assertEquals(null, table1.getBoolean("value"));
        Assert.assertEquals(null, table1.getByte("value"));
        Assert.assertEquals(null, table1.getShort("value"));
        Assert.assertEquals(null, table1.getCharacter("value"));
        Assert.assertEquals(null, table1.getDouble("value"));
        Assert.assertEquals(null, table1.getFloat("value"));
        Assert.assertEquals(null, table1.getInteger("value"));
        Assert.assertEquals(null, table1.getLong("value"));
        assertBytesEqual(bytes, table1.getBytes("value"));

        // ... and a the string value of it is null
        Assert.assertEquals(null, table1.getString("value"));

        table1.remove("value");
        // but after a removeKey it doesn't
        Assert.assertFalse(table1.containsKey("value"));

        // Table should now have zero length for encoding
        checkEmpty(table1);

        // Looking up an invalid value returns null
        Assert.assertEquals(null, table1.getBytes("Rubbish"));
    }

    /**
     * Calls all methods that can be used to check the table is empty
     * - getEncodedSize
     * - isEmpty
     * - length
     *
     * @param table to check is empty
     */
    private void checkEmpty(FieldTable table)
    {
        assertEquals(0, table.getEncodedSize());
        assertTrue(table.isEmpty());
        assertEquals(0, table.size());
    }

    /**
     * Set a String and check that we can only get it back as a String
     * Check that attempting to lookup a non existent value returns null
     */
    public void testString()
    {
        FieldTable table1 = new FieldTable();
        table1.setString("value", "Hello");
        Assert.assertTrue(table1.propertyExists("value"));

        // Test lookups we shouldn't get anything back for other gets
        // we should get right value back for this type ....
        Assert.assertEquals(null, table1.getBoolean("value"));
        Assert.assertEquals(null, table1.getByte("value"));
        Assert.assertEquals(null, table1.getShort("value"));
        Assert.assertEquals(null, table1.getCharacter("value"));
        Assert.assertEquals(null, table1.getDouble("value"));
        Assert.assertEquals(null, table1.getFloat("value"));
        Assert.assertEquals(null, table1.getInteger("value"));
        Assert.assertEquals(null, table1.getLong("value"));
        Assert.assertEquals(null, table1.getBytes("value"));
        Assert.assertEquals("Hello", table1.getString("value"));

        // Try setting a null value and read it back
        table1.setString("value", null);

        Assert.assertEquals(null, table1.getString("value"));

        // but still contains the value
        Assert.assertTrue(table1.containsKey("value"));

        table1.remove("value");
        // but after a removeKey it doesn't
        Assert.assertFalse(table1.containsKey("value"));

        checkEmpty(table1);

        // Looking up an invalid value returns null
        Assert.assertEquals(null, table1.getString("Rubbish"));

        // Additional Test that haven't been covered for string
        table1.setObject("value", "Hello");
        // Check that it was set correctly
        Assert.assertEquals("Hello", table1.getString("value"));
    }

    /** Check that a nested field table parameter correctly encodes and decodes to a byte buffer. */
    public void testNestedFieldTable() throws IOException
    {
        byte[] testBytes = new byte[] { 0, 1, 2, 3, 4, 5 };

        FieldTable outerTable = new FieldTable();
        FieldTable innerTable = new FieldTable();

        // Put some stuff in the inner table.
        innerTable.setBoolean("bool", true);
        innerTable.setByte("byte", Byte.MAX_VALUE);
        innerTable.setBytes("bytes", testBytes);
        innerTable.setChar("char", 'c');
        innerTable.setDouble("double", Double.MAX_VALUE);
        innerTable.setFloat("float", Float.MAX_VALUE);
        innerTable.setInteger("int", Integer.MAX_VALUE);
        innerTable.setLong("long", Long.MAX_VALUE);
        innerTable.setShort("short", Short.MAX_VALUE);
        innerTable.setString("string", "hello");
        innerTable.setString("null-string", null);
        innerTable.setFieldArray("field-array",Arrays.asList("hello",Integer.valueOf(42), Collections.emptyList()));

        // Put the inner table in the outer one.
        outerTable.setFieldTable("innerTable", innerTable);

        // Write the outer table into the buffer.
        QpidByteBuffer buf = QpidByteBuffer.allocate(EncodingUtils.encodedFieldTableLength(outerTable));

        outerTable.writeToBuffer(buf);

        buf.flip();

        // Extract the table back from the buffer again.
        try
        {
            FieldTable extractedOuterTable = EncodingUtils.readFieldTable(buf);

            FieldTable extractedTable = extractedOuterTable.getFieldTable("innerTable");

            Assert.assertEquals(Boolean.TRUE, extractedTable.getBoolean("bool"));
            Assert.assertEquals(Byte.valueOf(Byte.MAX_VALUE), extractedTable.getByte("byte"));
            assertBytesEqual(testBytes, extractedTable.getBytes("bytes"));
            Assert.assertEquals(Character.valueOf('c'), extractedTable.getCharacter("char"));
            Assert.assertEquals(Double.valueOf(Double.MAX_VALUE), extractedTable.getDouble("double"));
            Assert.assertEquals(Float.valueOf(Float.MAX_VALUE), extractedTable.getFloat("float"));
            Assert.assertEquals(Integer.valueOf(Integer.MAX_VALUE), extractedTable.getInteger("int"));
            Assert.assertEquals(Long.valueOf(Long.MAX_VALUE), extractedTable.getLong("long"));
            Assert.assertEquals(Short.valueOf(Short.MAX_VALUE), extractedTable.getShort("short"));
            Assert.assertEquals("hello", extractedTable.getString("string"));
            Assert.assertNull(extractedTable.getString("null-string"));
            Collection fieldArray = (Collection) extractedTable.get("field-array");
            Assert.assertEquals(3, fieldArray.size());
            Iterator iter = fieldArray.iterator();
            assertEquals("hello",iter.next());
            assertEquals(Integer.valueOf(42), iter.next());
            assertTrue(((Collection)iter.next()).isEmpty());
        }
        catch (AMQFrameDecodingException e)
        {
            fail("Failed to decode field table with nested inner table.");
        }
    }

    public void testValues()
    {
        FieldTable table = new FieldTable();
        table.setBoolean("bool", true);
        table.setByte("byte", Byte.MAX_VALUE);
        byte[] bytes = { 99, 98, 97, 96, 95 };
        table.setBytes("bytes", bytes);
        table.setChar("char", 'c');
        table.setDouble("double", Double.MAX_VALUE);
        table.setFloat("float", Float.MAX_VALUE);
        table.setInteger("int", Integer.MAX_VALUE);
        table.setLong("long", Long.MAX_VALUE);
        table.setShort("short", Short.MAX_VALUE);
        table.setString("string", "Hello");
        table.setString("null-string", null);

        table.setObject("object-bool", true);
        table.setObject("object-byte", Byte.MAX_VALUE);
        table.setObject("object-bytes", bytes);
        table.setObject("object-char", 'c');
        table.setObject("object-double", Double.MAX_VALUE);
        table.setObject("object-float", Float.MAX_VALUE);
        table.setObject("object-int", Integer.MAX_VALUE);
        table.setObject("object-long", Long.MAX_VALUE);
        table.setObject("object-short", Short.MAX_VALUE);
        table.setObject("object-string", "Hello");

        try
        {
            table.setObject("Null-object", null);
            fail("null values are not allowed");
        }
        catch (AMQPInvalidClassException aice)
        {
            assertEquals("Null values are not allowed to be set",
                    AMQPInvalidClassException.INVALID_OBJECT_MSG + "null", aice.getMessage());
        }

        try
        {
            table.setObject("Unsupported-object", new Exception());
            fail("Non primitive values are not allowed");
        }
        catch (AMQPInvalidClassException aice)
        {
            assertEquals("Non primitive values are not allowed to be set",
                    AMQPInvalidClassException.INVALID_OBJECT_MSG + Exception.class, aice.getMessage());
        }

        Assert.assertEquals(Boolean.TRUE, table.getBoolean("bool"));
        Assert.assertEquals(Byte.valueOf(Byte.MAX_VALUE), table.getByte("byte"));
        assertBytesEqual(bytes, table.getBytes("bytes"));
        Assert.assertEquals(Character.valueOf('c'), table.getCharacter("char"));
        Assert.assertEquals(Double.valueOf(Double.MAX_VALUE), table.getDouble("double"));
        Assert.assertEquals(Float.valueOf(Float.MAX_VALUE), table.getFloat("float"));
        Assert.assertEquals(Integer.valueOf(Integer.MAX_VALUE), table.getInteger("int"));
        Assert.assertEquals(Long.valueOf(Long.MAX_VALUE), table.getLong("long"));
        Assert.assertEquals(Short.valueOf(Short.MAX_VALUE), table.getShort("short"));
        Assert.assertEquals("Hello", table.getString("string"));
        Assert.assertNull(table.getString("null-string"));

        Assert.assertEquals(true, table.getObject("object-bool"));
        Assert.assertEquals(Byte.MAX_VALUE, table.getObject("object-byte"));
        assertBytesEqual(bytes, (byte[]) table.getObject("object-bytes"));
        Assert.assertEquals('c', table.getObject("object-char"));
        Assert.assertEquals(Double.MAX_VALUE, table.getObject("object-double"));
        Assert.assertEquals(Float.MAX_VALUE, table.getObject("object-float"));
        Assert.assertEquals(Integer.MAX_VALUE, table.getObject("object-int"));
        Assert.assertEquals(Long.MAX_VALUE, table.getObject("object-long"));
        Assert.assertEquals(Short.MAX_VALUE, table.getObject("object-short"));
        Assert.assertEquals("Hello", table.getObject("object-string"));
    }

    public void testWriteBuffer() throws IOException
    {
        byte[] bytes = { 99, 98, 97, 96, 95 };

        FieldTable table = new FieldTable();
        table.setBoolean("bool", true);
        table.setByte("byte", Byte.MAX_VALUE);

        table.setBytes("bytes", bytes);
        table.setChar("char", 'c');
        table.setInteger("int", Integer.MAX_VALUE);
        table.setLong("long", Long.MAX_VALUE);
        table.setDouble("double", Double.MAX_VALUE);
        table.setFloat("float", Float.MAX_VALUE);
        table.setShort("short", Short.MAX_VALUE);
        table.setString("string", "hello");
        table.setString("null-string", null);


        QpidByteBuffer buf = QpidByteBuffer.allocate((int) table.getEncodedSize() + 4);
        table.writeToBuffer(buf);

        buf.flip();

        long length = buf.getInt() & 0xFFFFFFFFL;
        QpidByteBuffer bufSlice = buf.slice();
        bufSlice.limit((int)length);


        FieldTable table2 = new FieldTable(bufSlice);

        Assert.assertEquals((Boolean) true, table2.getBoolean("bool"));
        Assert.assertEquals((Byte) Byte.MAX_VALUE, table2.getByte("byte"));
        assertBytesEqual(bytes, table2.getBytes("bytes"));
        Assert.assertEquals((Character) 'c', table2.getCharacter("char"));
        Assert.assertEquals(Double.valueOf(Double.MAX_VALUE), table2.getDouble("double"));
        Assert.assertEquals(Float.valueOf(Float.MAX_VALUE), table2.getFloat("float"));
        Assert.assertEquals(Integer.valueOf(Integer.MAX_VALUE), table2.getInteger("int"));
        Assert.assertEquals(Long.valueOf(Long.MAX_VALUE), table2.getLong("long"));
        Assert.assertEquals(Short.valueOf(Short.MAX_VALUE), table2.getShort("short"));
        Assert.assertEquals("hello", table2.getString("string"));
        Assert.assertNull(table2.getString("null-string"));
        buf.dispose();
        bufSlice.dispose();
        table.dispose();
        table2.dispose();
    }

    public void testEncodingSize()
    {
        FieldTable result = new FieldTable();
        int size = 0;

        result.setBoolean("boolean", true);
        size += 1 + EncodingUtils.encodedShortStringLength("boolean") + EncodingUtils.encodedBooleanLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setByte("byte", (byte) Byte.MAX_VALUE);
        size += 1 + EncodingUtils.encodedShortStringLength("byte") + EncodingUtils.encodedByteLength();
        Assert.assertEquals(size, result.getEncodedSize());

        byte[] _bytes = { 99, 98, 97, 96, 95 };

        result.setBytes("bytes", _bytes);
        size += 1 + EncodingUtils.encodedShortStringLength("bytes") + 4 + _bytes.length;
        Assert.assertEquals(size, result.getEncodedSize());

        result.setChar("char", (char) 'c');
        size += 1 + EncodingUtils.encodedShortStringLength("char") + EncodingUtils.encodedCharLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setDouble("double", (double) Double.MAX_VALUE);
        size += 1 + EncodingUtils.encodedShortStringLength("double") + EncodingUtils.encodedDoubleLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setFloat("float", (float) Float.MAX_VALUE);
        size += 1 + EncodingUtils.encodedShortStringLength("float") + EncodingUtils.encodedFloatLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setInteger("int", (int) Integer.MAX_VALUE);
        size += 1 + EncodingUtils.encodedShortStringLength("int") + EncodingUtils.encodedIntegerLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setLong("long", (long) Long.MAX_VALUE);
        size += 1 + EncodingUtils.encodedShortStringLength("long") + EncodingUtils.encodedLongLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setShort("short", (short) Short.MAX_VALUE);
        size += 1 + EncodingUtils.encodedShortStringLength("short") + EncodingUtils.encodedShortLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setString("result", "Hello");
        size += 1 + EncodingUtils.encodedShortStringLength("result") + EncodingUtils.encodedLongStringLength("Hello");
        Assert.assertEquals(size, result.getEncodedSize());

        result.setObject("object-bool", true);
        size += 1 + EncodingUtils.encodedShortStringLength("object-bool") + EncodingUtils.encodedBooleanLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setObject("object-byte", Byte.MAX_VALUE);
        size += 1 + EncodingUtils.encodedShortStringLength("object-byte") + EncodingUtils.encodedByteLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setObject("object-bytes", _bytes);
        size += 1 + EncodingUtils.encodedShortStringLength("object-bytes") + 4 + _bytes.length;
        Assert.assertEquals(size, result.getEncodedSize());

        result.setObject("object-char", 'c');
        size += 1 + EncodingUtils.encodedShortStringLength("object-char") + EncodingUtils.encodedCharLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setObject("object-double", Double.MAX_VALUE);
        size += 1 + EncodingUtils.encodedShortStringLength("object-double") + EncodingUtils.encodedDoubleLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setObject("object-float", Float.MAX_VALUE);
        size += 1 + EncodingUtils.encodedShortStringLength("object-float") + EncodingUtils.encodedFloatLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setObject("object-int", Integer.MAX_VALUE);
        size += 1 + EncodingUtils.encodedShortStringLength("object-int") + EncodingUtils.encodedIntegerLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setObject("object-long", Long.MAX_VALUE);
        size += 1 + EncodingUtils.encodedShortStringLength("object-long") + EncodingUtils.encodedLongLength();
        Assert.assertEquals(size, result.getEncodedSize());

        result.setObject("object-short", Short.MAX_VALUE);
        size += 1 + EncodingUtils.encodedShortStringLength("object-short") + EncodingUtils.encodedShortLength();
        Assert.assertEquals(size, result.getEncodedSize());
    }

    /**
     * Additional test for setObject
     */
    public void testSetObject()
    {
        FieldTable table = new FieldTable();

        // Try setting a non primative object

        try
        {
            table.setObject("value", this);
            fail("Only primative values allowed in setObject");
        }
        catch (AMQPInvalidClassException iae)
        {
            // normal path
        }
        // so length should be zero
        Assert.assertEquals(0, table.getEncodedSize());
    }

    /**
     * Additional test checkPropertyName doesn't accept Null
     */
    public void testCheckPropertyNameasNull()
    {
        FieldTable table = new FieldTable();

        try
        {
            table.setObject((String) null, "String");
            fail("Null property name is not allowed");
        }
        catch (IllegalArgumentException iae)
        {
            // normal path
        }
        // so length should be zero
        Assert.assertEquals(0, table.getEncodedSize());
    }

    /**
     * Additional test checkPropertyName doesn't accept an empty String
     */
    public void testCheckPropertyNameasEmptyString()
    {
        FieldTable table = new FieldTable();

        try
        {
            table.setObject("", "String");
            fail("empty property name is not allowed");
        }
        catch (IllegalArgumentException iae)
        {
            // normal path
        }
        // so length should be zero
        Assert.assertEquals(0, table.getEncodedSize());
    }

    /**
     * Additional test checkPropertyName doesn't accept an empty String
     */
    public void testCheckPropertyNamehasMaxLength()
    {
        FieldTable table = new FieldTable(true);

        StringBuffer longPropertyName = new StringBuffer(129);

        for (int i = 0; i < 129; i++)
        {
            longPropertyName.append("x");
        }

        try
        {
            table.setObject(longPropertyName.toString(), "String");
            fail("property name must be < 128 characters");
        }
        catch (IllegalArgumentException iae)
        {
            // normal path
        }
        // so length should be zero
        Assert.assertEquals(0, table.getEncodedSize());
    }

    /**
     * Additional test checkPropertyName starts with a letter
     */
    public void testCheckPropertyNameStartCharacterIsLetter()
    {
        FieldTable table = new FieldTable(true);

        // Try a name that starts with a number
        try
        {
            table.setObject("1", "String");
            fail("property name must start with a letter");
        }
        catch (IllegalArgumentException iae)
        {
            // normal path
        }
        // so length should be zero
        Assert.assertEquals(0, table.getEncodedSize());
    }

    /**
     * Additional test checkPropertyName starts with a hash or a dollar
     */
    public void testCheckPropertyNameStartCharacterIsHashorDollar()
    {
        FieldTable table = new FieldTable(true);

        // Try a name that starts with a number
        try
        {
            table.setObject("#", "String");
            table.setObject("$", "String");
        }
        catch (IllegalArgumentException iae)
        {
            fail("property name are allowed to start with # and $s");
        }
    }

    /**
     * Additional test to test the contents of the table
     */
    public void testContents()
    {
        FieldTable table = new FieldTable();

        table.setObject("StringProperty", "String");

        Assert.assertEquals("String", table.getString("StringProperty"));

        // Test Clear

        table.clear();

        checkEmpty(table);
    }

    /**
     * Test the contents of the sets
     */
    public void testSets()
    {

        FieldTable table = new FieldTable();

        table.setObject("n1", "1");
        table.setObject("n2", "2");
        table.setObject("n3", "3");

        Assert.assertEquals("1", table.getObject("n1"));
        Assert.assertEquals("2", table.getObject("n2"));
        Assert.assertEquals("3", table.getObject("n3"));
    }

    public void testAddAll()
    {
        final FieldTable table1 = new FieldTable();
        table1.setInteger("int1", 1);
        table1.setInteger("int2", 2);
        assertEquals("Unexpected number of entries in table1", 2, table1.size());

        final FieldTable table2 = new FieldTable();
        table2.setInteger("int3", 3);
        table2.setInteger("int4", 4);
        assertEquals("Unexpected number of entries in table2", 2, table2.size());

        table1.addAll(table2);
        assertEquals("Unexpected number of entries in table1 after addAll", 4, table1.size());
        assertEquals(Integer.valueOf(3), table1.getInteger("int3"));
    }

    public void testAddAllWithEmptyFieldTable()
    {
        final FieldTable table1 = new FieldTable();
        table1.setInteger("int1", 1);
        table1.setInteger("int2", 2);
        assertEquals("Unexpected number of entries in table1", 2, table1.size());

        final FieldTable emptyFieldTable = new FieldTable();

        table1.addAll(emptyFieldTable);
        assertEquals("Unexpected number of entries in table1 after addAll", 2, table1.size());
    }

    /**
     * Tests that when copying properties into a new FielTable using the addAll() method, the
     *  properties are successfully added to the destination table when the source FieldTable
     * was created from encoded input bytes,
     */
    public void testAddingAllFromFieldTableCreatedUsingEncodedBytes() throws Exception
    {
        String myBooleanTestProperty = "myBooleanTestProperty";

        //Create a new FieldTable and use it to encode data into a byte array.
        FieldTable encodeTable = new FieldTable();
        encodeTable.setObject(myBooleanTestProperty, true);
        byte[] data = encodeTable.getDataAsBytes();
        int length = data.length;

        //Verify we got the expected mount of encoded data (1B type hdr + 21B for name + 1B type hdr + 1B for boolean)
        assertEquals("unexpected data length", 24, length);

        //Create a second FieldTable from the encoded bytes
        FieldTable tableFromBytes = new FieldTable(QpidByteBuffer.wrap(data));

        //Create a final FieldTable and addAll() from the table created with encoded bytes
        FieldTable destinationTable = new FieldTable();
        assertTrue("unexpected size", destinationTable.isEmpty());
        destinationTable.addAll(tableFromBytes);

        //Verify that the destination table now contains the expected entry
        assertEquals("unexpected size", 1, destinationTable.size());
        assertTrue("expected property not present", destinationTable.containsKey(myBooleanTestProperty));
        assertTrue("unexpected property value", destinationTable.getBoolean(myBooleanTestProperty));
    }

    public void testValidateMalformedFieldTable()
    {
        final FieldTable fieldTable = buildMalformedFieldTable();

        try
        {
            fieldTable.validate();
            fail("Exception is expected");
        }
        catch (RuntimeException e)
        {
            // pass
        }
    }

    public void testValidateCorrectFieldTable()
    {
        final FieldTable ft = FieldTable.convertToFieldTable(Collections.singletonMap("testKey", "testValue"));
        final int encodedSize = (int)ft.getEncodedSize() + Integer.BYTES;
        final QpidByteBuffer buf = QpidByteBuffer.allocate(encodedSize);
        ft.writeToBuffer(buf);
        buf.flip();
        buf.position(Integer.BYTES);

        final FieldTable fieldTable = new FieldTable(buf);
        assertEquals(1, fieldTable.size());
        fieldTable.validate();
        assertTrue("Expected key is not found", fieldTable.containsKey("testKey"));
    }

    private FieldTable buildMalformedFieldTable()
    {
        final QpidByteBuffer buf = QpidByteBuffer.allocate(1);
        buf.put((byte) -1);

        buf.flip();

        return new FieldTable(buf);
    }

    private void assertBytesEqual(byte[] expected, byte[] actual)
    {
        Assert.assertEquals(expected.length, actual.length);

        for (int index = 0; index < expected.length; index++)
        {
            Assert.assertEquals(expected[index], actual[index]);
        }
    }

    public static junit.framework.Test suite()
    {
        return new junit.framework.TestSuite(FieldTableTest.class);
    }

}
