/*
 * 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.lisp.msg.protocols;

import com.google.common.collect.ImmutableList;
import com.google.common.testing.EqualsTester;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onosproject.lisp.msg.exceptions.LispParseError;
import org.onosproject.lisp.msg.exceptions.LispReaderException;
import org.onosproject.lisp.msg.protocols.DefaultLispMapRequest.DefaultRequestBuilder;
import org.onosproject.lisp.msg.protocols.DefaultLispMapRequest.RequestReader;
import org.onosproject.lisp.msg.protocols.DefaultLispMapRequest.RequestWriter;
import org.onosproject.lisp.msg.protocols.LispMapRequest.RequestBuilder;
import org.onosproject.lisp.msg.types.LispAfiAddress;
import org.onosproject.lisp.msg.exceptions.LispWriterException;
import org.onosproject.lisp.msg.types.LispIpv4Address;

import java.util.List;

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

/**
 * Unit tests for DefaultLispMapRequest class.
 */
public final class DefaultLispMapRequestTest {

    private static final String EID_IP_ADDRESS_1 = "192.168.1.1";
    private static final String EID_IP_ADDRESS_2 = "192.168.1.1";

    private static final String RLOC_IP_ADDRESS_1_1 = "10.1.1.1";
    private static final String RLOC_IP_ADDRESS_1_2 = "10.1.1.2";
    private static final String RLOC_IP_ADDRESS_2_1 = "20.1.1.1";
    private static final String RLOC_IP_ADDRESS_2_2 = "20.1.1.2";

    private LispMapRequest request1;
    private LispMapRequest sameAsRequest1;
    private LispMapRequest request2;

    @Before
    public void setup() {

        RequestBuilder builder1 = new DefaultRequestBuilder();

        LispIpv4Address ipv4Eid1 = new LispIpv4Address(IpAddress.valueOf(EID_IP_ADDRESS_1));

        LispIpv4Address ipv4Rloc1 = new LispIpv4Address(IpAddress.valueOf(RLOC_IP_ADDRESS_1_1));
        LispIpv4Address ipv4Rloc2 = new LispIpv4Address(IpAddress.valueOf(RLOC_IP_ADDRESS_1_2));

        List<LispAfiAddress> rlocs1 = ImmutableList.of(ipv4Rloc1, ipv4Rloc2);
        List<LispEidRecord> records1 = ImmutableList.of(getEidRecord(), getEidRecord());

        request1 = builder1
                        .withIsAuthoritative(true)
                        .withIsMapDataPresent(true)
                        .withIsPitr(false)
                        .withIsProbe(false)
                        .withIsSmr(true)
                        .withIsSmrInvoked(false)
                        .withSourceEid(ipv4Eid1)
                        .withItrRlocs(rlocs1)
                        .withEidRecords(records1)
                        .withNonce(1L)
                        .withReplyRecord(1)
                        .build();

        RequestBuilder builder2 = new DefaultRequestBuilder();
        List<LispEidRecord> records2 = ImmutableList.of(getEidRecord(), getEidRecord());

        sameAsRequest1 = builder2
                        .withIsAuthoritative(true)
                        .withIsMapDataPresent(true)
                        .withIsPitr(false)
                        .withIsProbe(false)
                        .withIsSmr(true)
                        .withIsSmrInvoked(false)
                        .withSourceEid(ipv4Eid1)
                        .withItrRlocs(rlocs1)
                        .withEidRecords(records2)
                        .withNonce(1L)
                        .withReplyRecord(1)
                        .build();

        RequestBuilder builder3 = new DefaultRequestBuilder();

        LispIpv4Address ipv4Eid2 = new LispIpv4Address(IpAddress.valueOf(EID_IP_ADDRESS_2));

        LispIpv4Address ipv4Rloc3 = new LispIpv4Address(IpAddress.valueOf(RLOC_IP_ADDRESS_2_1));
        LispIpv4Address ipv4Rloc4 = new LispIpv4Address(IpAddress.valueOf(RLOC_IP_ADDRESS_2_2));

        List<LispAfiAddress> rlocs2 = ImmutableList.of(ipv4Rloc3, ipv4Rloc4);

        request2 = builder3
                        .withIsAuthoritative(false)
                        .withIsMapDataPresent(false)
                        .withIsPitr(true)
                        .withIsProbe(true)
                        .withIsSmr(false)
                        .withIsSmrInvoked(true)
                        .withSourceEid(ipv4Eid2)
                        .withItrRlocs(rlocs2)
                        .withNonce(2L)
                        .withReplyRecord(2)
                        .build();
    }

    private LispEidRecord getEidRecord() {
        LispIpv4Address eid = new LispIpv4Address(IpAddress.valueOf(RLOC_IP_ADDRESS_2_1));
        return new LispEidRecord((byte) 24, eid);
    }

    @Test
    public void testEquality() {
        new EqualsTester()
                .addEqualityGroup(request1, sameAsRequest1)
                .addEqualityGroup(request2).testEquals();
    }

    @Test
    public void testConstruction() {
        DefaultLispMapRequest request = (DefaultLispMapRequest) request1;

        assertThat(request.isAuthoritative(), is(true));
        assertThat(request.isMapDataPresent(), is(true));
        assertThat(request.isPitr(), is(false));
        assertThat(request.isProbe(), is(false));
        assertThat(request.isSmr(), is(true));
        assertThat(request.isSmrInvoked(), is(false));
        assertThat(request.getNonce(), is(1L));
        assertThat(request.getRecordCount(), is(2));
        assertThat(request.getReplyRecord(), is(1));
    }

    @Test
    public void testSerialization() throws LispReaderException, LispWriterException, LispParseError {
        ByteBuf byteBuf = Unpooled.buffer();
        RequestWriter writer = new RequestWriter();
        writer.writeTo(byteBuf, request1);

        RequestReader reader = new RequestReader();
        LispMapRequest deserialized = reader.readFrom(byteBuf);

        new EqualsTester().addEqualityGroup(request1, deserialized).testEquals();
    }
}
