//:: # Copyright 2013, Big Switch Networks, Inc.
//:: #
//:: # LoxiGen is licensed under the Eclipse Public License, version 1.0 (EPL), with
//:: # the following special exception:
//:: #
//:: # LOXI Exception
//:: #
//:: # As a special exception to the terms of the EPL, you may distribute libraries
//:: # generated by LoxiGen (LoxiGen Libraries) under the terms of your choice, provided
//:: # that copyright and licensing notices generated by LoxiGen are not altered or removed
//:: # from the LoxiGen Libraries and the notice provided below is (i) included in
//:: # the LoxiGen Libraries, if distributed in source code form and (ii) included in any
//:: # documentation for the LoxiGen Libraries, if distributed in binary form.
//:: #
//:: # Notice: "Copyright 2013, Big Switch Networks, Inc. This library was generated by the LoxiGen Compiler."
//:: #
//:: # You may not use this file except in compliance with the EPL or LOXI Exception. You may obtain
//:: # a copy of the EPL at:
//:: #
//:: # http::: #www.eclipse.org/legal/epl-v10.html
//:: #
//:: # 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
//:: # EPL for the specific language governing permissions and limitations
//:: # under the EPL.
//::
//:: from loxi_ir import *
//:: import itertools
//:: import of_g
//:: include('_copyright.java')

//:: include('_autogen.java')

package ${test.package};

//:: include("_imports.java", msg=msg)
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;

public class ${test.name} {
    //:: var_type = msg.interface.name
    //:: var_name = msg.interface.variable_name
    OFFactory factory;

    final static byte[] ${msg.constant_name}_SERIALIZED =
        new byte[] { ${", ".join("%s0x%x" % (("" if ord(c)<128 else "(byte) "),  ord(c)) for c in test_data["binary"] ) } };

    @Before
    public void setup() {
        factory = OFFactories.getFactory(OFVersion.${version.constant_version});
    }

    //:: if "java" in test_data:
    @Test
    public void testWrite() {
        ${var_type}.Builder builder = factory.build${var_type[2:]}();
        ${test_data["java"]};
        ${var_type} ${var_name} = builder.build();
        ChannelBuffer bb = ChannelBuffers.dynamicBuffer();
        ${var_name}.writeTo(bb);
        byte[] written = new byte[bb.readableBytes()];
        bb.readBytes(written);

        assertArrayEquals(${msg.constant_name}_SERIALIZED, written);
    }

    @Test
    public void testRead() throws Exception {
        ${var_type}.Builder builder = factory.build${var_type[2:]}();
        ${test_data["java"]};
        ${var_type} ${var_name}Built = builder.build();

        ChannelBuffer input = ChannelBuffers.copiedBuffer(${msg.constant_name}_SERIALIZED);

        // FIXME should invoke the overall reader once implemented
        ${var_type} ${var_name}Read = ${msg.name}.READER.readFrom(input);

        assertEquals(${var_name}Built, ${var_name}Read);
   }
   //:: else:
   // FIXME: No java stanza in test_data for this class. Add for more comprehensive unit testing
   //:: #endif

   @Test
   public void testReadWrite() throws Exception {
       ChannelBuffer input = ChannelBuffers.copiedBuffer(${msg.constant_name}_SERIALIZED);

       // FIXME should invoke the overall reader once implemented
       ${var_type} ${var_name} = ${msg.name}.READER.readFrom(input);

       // write message again
       ChannelBuffer bb = ChannelBuffers.dynamicBuffer();
       ${var_name}.writeTo(bb);
       byte[] written = new byte[bb.readableBytes()];
       bb.readBytes(written);

       assertArrayEquals(${msg.constant_name}_SERIALIZED, written);
   }

}
