/*
 * Copyright 2016 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.controller.impl;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.Ip4Address;
import org.onlab.util.Bandwidth;

import java.util.ArrayList;
import java.util.List;

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

/**
 * Unit test class for OspfDeviceTedImpl.
 */
public class OspfLinkTedImplTest {
    private static final Ip4Address LOCAL_ADDRESS = Ip4Address.valueOf("127.0.0.1");

    private OspfLinkTedImpl ospfLinkTed;

    @Before
    public void setUp() throws Exception {
        ospfLinkTed = new OspfLinkTedImpl();
    }

    @After
    public void tearDown() throws Exception {
        ospfLinkTed = null;
    }

    /**
     * Tests maximumLink() getter method.
     */
    @Test
    public void testMaximumLink() throws Exception {

        ospfLinkTed.setMaximumLink(Bandwidth.bps(1234));
        assertThat(ospfLinkTed.maximumLink(), is(Bandwidth.bps(1234)));
    }

    /**
     * Tests maximumLink() setter method.
     */
    @Test
    public void testSetMaximumLink() throws Exception {
        ospfLinkTed.setMaximumLink(Bandwidth.bps(1234));
        assertThat(ospfLinkTed.maximumLink(), is(Bandwidth.bps(1234)));
    }

    /**
     * Tests ipv6RemRouterId() getter method.
     */
    @Test
    public void testIpv6RemRouterId() throws Exception {
        List list = new ArrayList();
        ospfLinkTed.setIpv6RemRouterId(list);
        assertThat(ospfLinkTed.ipv6RemRouterId().size(), is(0));
    }

    /**
     * Tests ipv6RemRouterId() setter method.
     */
    @Test
    public void testSetIpv6RemRouterId() throws Exception {
        List list = new ArrayList();
        ospfLinkTed.setIpv6RemRouterId(list);
        assertThat(ospfLinkTed.ipv6RemRouterId().size(), is(0));
    }

    /**
     * Tests ipv4RemRouterId() getter method.
     */
    @Test
    public void testIpv4RemRouterId() throws Exception {
        List list = new ArrayList();
        list.add(LOCAL_ADDRESS);
        ospfLinkTed.setIpv4RemRouterId(list);
        assertThat(ospfLinkTed.ipv4RemRouterId().size(), is(1));
    }

    /**
     * Tests ipv4RemRouterId() setter method.
     */
    @Test
    public void testSetIpv4RemRouterId() throws Exception {
        List list = new ArrayList();
        list.add(LOCAL_ADDRESS);
        ospfLinkTed.setIpv4RemRouterId(list);
        assertThat(ospfLinkTed.ipv4RemRouterId().size(), is(1));
    }

    /**
     * Tests ipv6LocRouterId() getter method.
     */
    @Test
    public void testIpv6LocRouterId() throws Exception {
        List list = new ArrayList();
        ospfLinkTed.setIpv4LocRouterId(list);
        assertThat(ospfLinkTed.ipv6LocRouterId().size(), is(0));
    }

    /**
     * Tests ipv6LocRouterId() setter method.
     */
    @Test
    public void testSetIpv6LocRouterId() throws Exception {
        List list = new ArrayList();
        ospfLinkTed.setIpv4LocRouterId(list);
        assertThat(ospfLinkTed.ipv6LocRouterId().size(), is(0));
    }

    /**
     * Tests ipv4LocRouterId() getter method.
     */
    @Test
    public void testIpv4LocRouterId() throws Exception {
        List list = new ArrayList();
        list.add(LOCAL_ADDRESS);
        ospfLinkTed.setIpv4LocRouterId(list);
        assertThat(ospfLinkTed.ipv4LocRouterId().size(), is(1));
    }

    /**
     * Tests ipv4LocRouterId() setter method.
     */
    @Test
    public void testSetIpv4LocRouterId() throws Exception {
        List list = new ArrayList();
        list.add(LOCAL_ADDRESS);
        ospfLinkTed.setIpv4LocRouterId(list);
        assertThat(ospfLinkTed.ipv4LocRouterId().size(), is(1));
    }

    /**
     * Tests teMetric() getter method.
     */
    @Test
    public void testTeMetric() throws Exception {
        ospfLinkTed.setTeMetric(1234);
        assertThat(ospfLinkTed.teMetric(), is(1234));
    }

    /**
     * Tests teMetric() setter method.
     */
    @Test
    public void testSetTeMetric() throws Exception {
        ospfLinkTed.setTeMetric(1234);
        assertThat(ospfLinkTed.teMetric(), is(1234));
    }

    /**
     * Tests maxReserved() getter method.
     */
    @Test
    public void testMaxReserved() throws Exception {
        ospfLinkTed.setMaxReserved(Bandwidth.bps(1234));
        assertThat(ospfLinkTed.maxReserved(), is(Bandwidth.bps(1234)));
    }

    /**
     * Tests maxReserved() setter method.
     */
    @Test
    public void testSetMaxReserved() throws Exception {
        ospfLinkTed.setMaxReserved(Bandwidth.bps(1234));
        assertThat(ospfLinkTed.maxReserved(), is(Bandwidth.bps(1234)));
    }

    /**
     * Tests maxUnResBandwidth() getter method.
     */
    @Test
    public void testMaxUnResBandwidth() throws Exception {
        ospfLinkTed.setMaxUnResBandwidth(Bandwidth.bps(1234));
        assertThat(ospfLinkTed.maxUnResBandwidth(), is(notNullValue()));
    }

    /**
     * Tests maxUnResBandwidth() setter method.
     */
    @Test
    public void testSetMaxUnResBandwidth() throws Exception {
        ospfLinkTed.setMaxUnResBandwidth(Bandwidth.bps(1234.0));
        assertThat(ospfLinkTed.maxUnResBandwidth(), is(notNullValue()));
    }
}
