/*
 * Copyright 2015 Open Networking Laboratory
 *
 * Licensed 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.onosproject.openflow.controller.impl;

import java.nio.charset.StandardCharsets;
import java.util.List;

import org.jboss.netty.buffer.ChannelBuffer;
import org.junit.Test;
import org.onosproject.openflow.OfMessageAdapter;
import org.projectfloodlight.openflow.protocol.OFMessage;

import com.google.common.collect.ImmutableList;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;

/**
 * Tests for the OpenFlow message encoder.
 */
public class OFMessageEncoderTest {

    static class MockOfMessage extends OfMessageAdapter {
        static int nextId = 1;
        final int id;

        MockOfMessage() {
            id = nextId++;
        }

        @Override
        public void writeTo(ChannelBuffer channelBuffer) {
            String message = "message" + Integer.toString(id) + " ";
            channelBuffer.writeBytes(message.getBytes(StandardCharsets.UTF_8));
        }
    }

    /**
     * Tests that encoding a non-list returns the object specified.
     *
     * @throws Exception on exception in the encoder
     */
    @Test
    public void testNoList() throws Exception {
        OFMessageEncoder encoder = new OFMessageEncoder();
        MockOfMessage message = new MockOfMessage();
        OFMessage returnedMessage =
                (OFMessage) encoder.encode(null, null, message);
        assertThat(message, is(returnedMessage));
    }

    /**
     * Tests that encoding a list returns the proper encoded payload.
     *
     * @throws Exception on exception in the encoder
     */
    @Test
    public void testList() throws Exception {
        OFMessageEncoder encoder = new OFMessageEncoder();
        MockOfMessage message1 = new MockOfMessage();
        MockOfMessage message2 = new MockOfMessage();
        MockOfMessage message3 = new MockOfMessage();
        List<MockOfMessage> messages = ImmutableList.of(message1, message2, message3);
        ChannelBuffer returnedChannel =
                (ChannelBuffer) encoder.encode(null, null, messages);
        assertThat(returnedChannel, notNullValue());
        byte[] channelBytes = returnedChannel.array();
        String expectedListMessage = "message1 message2 message3 ";
        String listMessage =
                (new String(channelBytes, StandardCharsets.UTF_8))
                        .substring(0, expectedListMessage.length());
        assertThat(listMessage, is(expectedListMessage));
    }
}
