/*
 * Copyright 2016-present 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.ospf.protocol.ospfpacket;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.Ip4Address;
import org.onosproject.ospf.protocol.ospfpacket.types.DdPacket;
import org.onosproject.ospf.protocol.ospfpacket.types.HelloPacket;
import org.onosproject.ospf.protocol.ospfpacket.types.LsAcknowledge;
import org.onosproject.ospf.protocol.ospfpacket.types.LsRequest;
import org.onosproject.ospf.protocol.ospfpacket.types.LsUpdate;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.junit.Assert.assertThat;

/**
 * Unit test class for OspfMessageWriter.
 */
public class OspfMessageWriterTest {

    private OspfMessageWriter ospfMessageWriter;
    private HelloPacket helloPacket;
    private DdPacket ddPacket;
    private LsAcknowledge lsAck;
    private LsRequest lsReq;
    private LsUpdate lsUpdate;

    @Before
    public void setUp() throws Exception {
        ospfMessageWriter = new OspfMessageWriter();
    }

    @After
    public void tearDown() throws Exception {
        ospfMessageWriter = null;
        helloPacket = null;
        ddPacket = null;
        lsAck = null;
        lsReq = null;
        lsUpdate = null;
    }

    /**
     * Tests writeToBuffer() method.
     */
    @Test
    public void testWriteToBuffer() throws Exception {
        helloPacket = new HelloPacket();
        helloPacket.setAuthType(1);
        helloPacket.setOspftype(1);
        helloPacket.setRouterId(Ip4Address.valueOf("10.226.165.164"));
        helloPacket.setAreaId(Ip4Address.valueOf("10.226.165.100"));
        helloPacket.setChecksum(201);
        helloPacket.setAuthentication(2);
        helloPacket.setOspfPacLength(48);
        helloPacket.setOspfVer(2);
        helloPacket.setNetworkMask(Ip4Address.valueOf("255.255.255.255"));
        helloPacket.setOptions(2); //not setting now
        helloPacket.setHelloInterval(10);
        helloPacket.setRouterPriority(1);
        helloPacket.setRouterDeadInterval(40);
        helloPacket.setDr(Ip4Address.valueOf("1.1.1.1"));
        helloPacket.setBdr(Ip4Address.valueOf("2.2.2.2"));
        helloPacket.addNeighbor(Ip4Address.valueOf("8.8.8.8"));
        helloPacket.setDestinationIp(Ip4Address.valueOf("5.5.5.5"));
        ospfMessageWriter.writeToBuffer(helloPacket, 7, 1);
        assertThat(ospfMessageWriter, is(notNullValue()));
    }

    @Test(expected = Exception.class)
    public void testWriteToBuffer1() throws Exception {

        ddPacket = new DdPacket();
        ddPacket.setAuthType(1);
        ddPacket.setOspftype(2);
        ddPacket.setRouterId(Ip4Address.valueOf("10.226.165.164"));
        ddPacket.setAreaId(Ip4Address.valueOf("10.226.165.100"));
        ddPacket.setChecksum(201);
        ddPacket.setAuthentication(2);
        ddPacket.setOspfPacLength(48);
        ddPacket.setOspfVer(2);
        ospfMessageWriter.writeToBuffer(ddPacket, 1, 1);
        assertThat(ospfMessageWriter, is(notNullValue()));
    }

    @Test(expected = Exception.class)
    public void testWriteToBuffer2() throws Exception {

        lsAck = new LsAcknowledge();
        lsAck.setAuthType(1);
        lsAck.setOspftype(5);
        lsAck.setRouterId(Ip4Address.valueOf("10.226.165.164"));
        lsAck.setAreaId(Ip4Address.valueOf("10.226.165.100"));
        lsAck.setChecksum(201);
        lsAck.setAuthentication(2);
        lsAck.setOspfPacLength(48);
        lsAck.setOspfVer(2);
        ospfMessageWriter.writeToBuffer(lsAck, 1, 1);
        assertThat(ospfMessageWriter, is(notNullValue()));
    }

    @Test(expected = Exception.class)
    public void testWriteToBuffer3() throws Exception {
        lsReq = new LsRequest();
        lsReq.setAuthType(1);
        lsReq.setOspftype(3);
        lsReq.setRouterId(Ip4Address.valueOf("10.226.165.164"));
        lsReq.setAreaId(Ip4Address.valueOf("10.226.165.100"));
        lsReq.setChecksum(201);
        lsReq.setAuthentication(2);
        lsReq.setOspfPacLength(48);
        lsReq.setOspfVer(2);
        ospfMessageWriter.writeToBuffer(lsReq, 1, 1);
        assertThat(ospfMessageWriter, is(notNullValue()));
    }

    @Test(expected = Exception.class)
    public void testWriteToBuffer4() throws Exception {
        lsUpdate = new LsUpdate();
        lsUpdate.setAuthType(1);
        lsUpdate.setOspftype(3);
        lsUpdate.setRouterId(Ip4Address.valueOf("10.226.165.164"));
        lsUpdate.setAreaId(Ip4Address.valueOf("10.226.165.100"));
        lsUpdate.setChecksum(201);
        lsUpdate.setAuthentication(2);
        lsUpdate.setOspfPacLength(48);
        lsUpdate.setOspfVer(2);
        ospfMessageWriter.writeToBuffer(lsUpdate, 1, 1);
        assertThat(ospfMessageWriter, is(notNullValue()));
    }

    /**
     * Tests writeToBuffer() method.
     */
    @Test(expected = Exception.class)
    public void testWriteToBuffer5() throws Exception {
        lsAck = new LsAcknowledge();
        lsAck.setAuthType(1);
        lsAck.setOspftype(5);
        lsAck.setRouterId(Ip4Address.valueOf("10.226.165.164"));
        lsAck.setAreaId(Ip4Address.valueOf("10.226.165.100"));
        lsAck.setChecksum(201);
        lsAck.setAuthentication(2);
        lsAck.setOspfPacLength(48);
        lsAck.setOspfVer(2);
        ospfMessageWriter.writeToBuffer(lsAck, 1, 1);
    }
}