/*
 * Copyright 2017-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.provider.lisp.mapping.util;

import com.google.common.collect.ImmutableList;
import org.junit.Before;
import org.junit.Test;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onosproject.drivers.lisp.extensions.LispAppDataAddress;
import org.onosproject.drivers.lisp.extensions.LispGcAddress;
import org.onosproject.drivers.lisp.extensions.LispListAddress;
import org.onosproject.drivers.lisp.extensions.LispMulticastAddress;
import org.onosproject.drivers.lisp.extensions.LispNatAddress;
import org.onosproject.drivers.lisp.extensions.LispNonceAddress;
import org.onosproject.drivers.lisp.extensions.LispSegmentAddress;
import org.onosproject.drivers.lisp.extensions.LispSrcDstAddress;
import org.onosproject.lisp.msg.protocols.DefaultLispLocator.DefaultLocatorBuilder;
import org.onosproject.lisp.msg.protocols.DefaultLispMapNotify.DefaultNotifyBuilder;
import org.onosproject.lisp.msg.protocols.DefaultLispMapRecord.DefaultMapRecordBuilder;
import org.onosproject.lisp.msg.protocols.DefaultLispMapReply.DefaultReplyBuilder;
import org.onosproject.lisp.msg.protocols.LispLocator;
import org.onosproject.lisp.msg.protocols.LispLocator.LocatorBuilder;
import org.onosproject.lisp.msg.protocols.LispMapNotify;
import org.onosproject.lisp.msg.protocols.LispMapNotify.NotifyBuilder;
import org.onosproject.lisp.msg.protocols.LispMapRecord;
import org.onosproject.lisp.msg.protocols.LispMapRecord.MapRecordBuilder;
import org.onosproject.lisp.msg.protocols.LispMapReply;
import org.onosproject.lisp.msg.protocols.LispMapReply.ReplyBuilder;
import org.onosproject.lisp.msg.protocols.LispMapReplyAction;
import org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum;
import org.onosproject.lisp.msg.types.LispAfiAddress;
import org.onosproject.lisp.msg.types.LispAsAddress;
import org.onosproject.lisp.msg.types.LispDistinguishedNameAddress;
import org.onosproject.lisp.msg.types.LispIpv4Address;
import org.onosproject.lisp.msg.types.LispIpv6Address;
import org.onosproject.lisp.msg.types.LispMacAddress;
import org.onosproject.lisp.msg.types.lcaf.LispAppDataLcafAddress;
import org.onosproject.lisp.msg.types.lcaf.LispAsLcafAddress;
import org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum;
import org.onosproject.lisp.msg.types.lcaf.LispGeoCoordinateLcafAddress;
import org.onosproject.lisp.msg.types.lcaf.LispLcafAddress;
import org.onosproject.lisp.msg.types.lcaf.LispListLcafAddress;
import org.onosproject.lisp.msg.types.lcaf.LispMulticastLcafAddress;
import org.onosproject.lisp.msg.types.lcaf.LispNatLcafAddress;
import org.onosproject.lisp.msg.types.lcaf.LispNonceLcafAddress;
import org.onosproject.lisp.msg.types.lcaf.LispSegmentLcafAddress;
import org.onosproject.lisp.msg.types.lcaf.LispSourceDestLcafAddress;
import org.onosproject.lisp.msg.types.lcaf.LispTeLcafAddress;
import org.onosproject.lisp.msg.types.lcaf.LispTeRecord;
import org.onosproject.mapping.MappingEntry;
import org.onosproject.mapping.MappingKey;
import org.onosproject.mapping.MappingTreatment;
import org.onosproject.mapping.MappingValue;
import org.onosproject.mapping.actions.MappingAction;
import org.onosproject.mapping.addresses.ASMappingAddress;
import org.onosproject.mapping.addresses.DNMappingAddress;
import org.onosproject.mapping.addresses.EthMappingAddress;
import org.onosproject.mapping.addresses.ExtensionMappingAddressWrapper;
import org.onosproject.mapping.addresses.IPMappingAddress;
import org.onosproject.mapping.addresses.MappingAddress;
import org.onosproject.net.DeviceId;

import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.AS;
import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.DISTINGUISHED_NAME;
import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.IP4;
import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.IP6;
import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.LCAF;
import static org.onosproject.lisp.msg.types.AddressFamilyIdentifierEnum.MAC;
import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.APPLICATION_DATA;
import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.GEO_COORDINATE;
import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.LIST;
import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.MULTICAST;
import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.NAT;
import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.NONCE;
import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.SEGMENT;
import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.SOURCE_DEST;
import static org.onosproject.lisp.msg.types.lcaf.LispCanonicalAddressFormatEnum.UNKNOWN;

/**
 * Mapping entry builder unit test.
 */
public class MappingEntryBuilderTest {

    private static final String IP_RECORD_ADDRESS = "192.168.1.1";
    private static final int IP_RECORD_MASK_LENGTH = 32;
    private static final int IP_LOCATOR_MASK_LENGTH = 32;

    private static final LispAfiAddress IPV4_ADDRESS_1 =
                         new LispIpv4Address(IpAddress.valueOf("1.2.3.4"));
    private static final LispAfiAddress IPV4_ADDRESS_2 =
                         new LispIpv4Address(IpAddress.valueOf("5.6.7.8"));
    private static final LispAfiAddress IPV6_ADDRESS =
                         new LispIpv6Address(IpAddress.valueOf(
                                 "1111:2222:3333:4444:5555:6666:7777:8885"));
    private static final LispAfiAddress MAC_ADDRESS =
                         new LispMacAddress(MacAddress.valueOf("00:00:00:00:00:01"));

    private static final IpPrefix IPV4_MAPPING_ADDRESS_1 = IpPrefix.valueOf("1.2.3.4/32");
    private static final IpPrefix IPV4_MAPPING_ADDRESS_2 = IpPrefix.valueOf("5.6.7.8/32");

    private static final IpPrefix IPV6_MAPPING_ADDRESS =
            IpPrefix.valueOf("1111:2222:3333:4444:5555:6666:7777:8885/128");
    private static final MacAddress MAC_MAPPING_ADDRESS =
                                        MacAddress.valueOf("00:00:00:00:00:01");

    private static final byte UNIQUE_BYTE = (byte) 0x01;
    private static final int UNIQUE_INT = 1;
    private static final short UNIQUE_SHORT = 1;
    private static final boolean UNIQUE_BOOLEAN = true;
    private static final long UNIQUE_LONG = 1L;
    private static final String UNIQUE_STRING = "onos";

    private static final String AUTH_KEY = "onos";

    private static final DeviceId DEVICE_ID = DeviceId.deviceId("lisp:10.1.1.2");

    @Before
    public void setUp() {

    }

    @Test
    public void testMapReplyConversion() {

        ReplyBuilder replyBuilder = new DefaultReplyBuilder();

        List<LispMapRecord> records = ImmutableList.of(getMapRecord(IP4, UNKNOWN));

        LispMapReply mapReply = replyBuilder
                                    .withIsEtr(true)
                                    .withIsProbe(false)
                                    .withIsSecurity(true)
                                    .withNonce(UNIQUE_LONG)
                                    .withMapRecords(records)
                                    .build();

        List<LispMapRecord> replyRecords = mapReply.getMapRecords();

        assertThat(replyRecords.size(), is(1));

        testMapRecordConversion(replyRecords.get(0));
    }

    @Test
    public void testMapNotifyConversion() {

        List<LispMapRecord> records = ImmutableList.of(getMapRecord(IP4, UNKNOWN));

        NotifyBuilder notifyBuilder = new DefaultNotifyBuilder();

        LispMapNotify mapNotify = notifyBuilder
                                    .withKeyId(UNIQUE_SHORT)
                                    .withAuthKey(AUTH_KEY)
                                    .withNonce(UNIQUE_LONG)
                                    .withMapRecords(records)
                                    .build();

        List<LispMapRecord> notifyRecords = mapNotify.getMapRecords();

        assertThat(notifyRecords.size(), is(1));

        testMapRecordConversion(notifyRecords.get(0));
    }

    @Test
    public void testIpv4AddressConversion() {
        IPMappingAddress address = (IPMappingAddress) getMappingAddressByAfiType(IP4, UNKNOWN);
        assertThat(address.ip(), is(IPV4_MAPPING_ADDRESS_1));
    }

    @Test
    public void testIpv6AddressConversion() {
        IPMappingAddress address = (IPMappingAddress) getMappingAddressByAfiType(IP6, UNKNOWN);
        assertThat(address.ip(), is(IPV6_MAPPING_ADDRESS));
    }

    @Test
    public void testMacAddressConversion() {
        EthMappingAddress address = (EthMappingAddress) getMappingAddressByAfiType(MAC, UNKNOWN);
        assertThat(address.mac(), is(MAC_MAPPING_ADDRESS));
    }

    @Test
    public void testAsAddressConversion() {
        ASMappingAddress address = (ASMappingAddress) getMappingAddressByAfiType(AS, UNKNOWN);
        assertThat(address.asNumber(), is(String.valueOf(UNIQUE_INT)));
    }

    @Test
    public void testDnAddressConversion() {
        DNMappingAddress address = (DNMappingAddress)
                        getMappingAddressByAfiType(DISTINGUISHED_NAME, UNKNOWN);
        assertThat(address.name(), is(UNIQUE_STRING));
    }

    @Test
    public void testListLcafAddressConversion() {
        LispListAddress address = (LispListAddress) ((ExtensionMappingAddressWrapper)
                getMappingAddressByAfiType(LCAF, LIST)).extensionMappingAddress();
        assertThat(((IPMappingAddress) address.getIpv4()).ip(), is(IPV4_MAPPING_ADDRESS_1));
        assertThat(((IPMappingAddress) address.getIpv6()).ip(), is(IPV6_MAPPING_ADDRESS));
    }

    @Test
    public void testSegmentLcafAddressConversion() {
        LispSegmentAddress address = (LispSegmentAddress) ((ExtensionMappingAddressWrapper)
                getMappingAddressByAfiType(LCAF, SEGMENT)).extensionMappingAddress();
        assertThat(((IPMappingAddress) address.getAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
        assertThat(address.getInstanceId(), is(UNIQUE_INT));
    }

    @Test
    public void testAsLcafAddressConversion() {
        org.onosproject.drivers.lisp.extensions.LispAsAddress address =
                (org.onosproject.drivers.lisp.extensions.LispAsAddress)
                ((ExtensionMappingAddressWrapper)
                        getMappingAddressByAfiType(LCAF,
                                LispCanonicalAddressFormatEnum.AS)).extensionMappingAddress();
        assertThat(((IPMappingAddress) address.getAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
        assertThat(address.getAsNumber(), is(UNIQUE_INT));
    }

    @Test
    public void testAppDataLcafAddressConversion() {
        LispAppDataAddress address = (LispAppDataAddress) ((ExtensionMappingAddressWrapper)
                getMappingAddressByAfiType(LCAF, APPLICATION_DATA)).extensionMappingAddress();
        assertThat(((IPMappingAddress) address.getAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
        assertThat(address.getProtocol(), is(UNIQUE_BYTE));
        assertThat(address.getIpTos(), is(UNIQUE_INT));
        assertThat(address.getLocalPortLow(), is(UNIQUE_SHORT));
        assertThat(address.getLocalPortHigh(), is(UNIQUE_SHORT));
        assertThat(address.getRemotePortLow(), is(UNIQUE_SHORT));
        assertThat(address.getRemotePortHigh(), is(UNIQUE_SHORT));
    }

    @Test
    public void testGcLcafAddressConversion() {
        LispGcAddress address = (LispGcAddress) ((ExtensionMappingAddressWrapper)
                getMappingAddressByAfiType(LCAF, GEO_COORDINATE)).extensionMappingAddress();
        assertThat(((IPMappingAddress) address.getAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
        assertThat(address.isNorth(), is(UNIQUE_BOOLEAN));
        assertThat(address.getLatitudeDegree(), is(UNIQUE_SHORT));
        assertThat(address.getLatitudeMinute(), is(UNIQUE_BYTE));
        assertThat(address.getLatitudeSecond(), is(UNIQUE_BYTE));
        assertThat(address.isEast(), is(UNIQUE_BOOLEAN));
        assertThat(address.getLongitudeDegree(), is(UNIQUE_SHORT));
        assertThat(address.getLongitudeMinute(), is(UNIQUE_BYTE));
        assertThat(address.getLongitudeSecond(), is(UNIQUE_BYTE));
        assertThat(address.getAltitude(), is(UNIQUE_INT));
    }

    @Test
    public void testNatLcafAddressConversion() {
        LispNatAddress address = (LispNatAddress) ((ExtensionMappingAddressWrapper)
                getMappingAddressByAfiType(LCAF, NAT)).extensionMappingAddress();
        assertThat(((IPMappingAddress)
                address.getPrivateEtrRlocAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
        assertThat(((IPMappingAddress)
                address.getGlobalEtrRlocAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
        assertThat(((IPMappingAddress)
                address.getMsRlocAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
        assertThat(address.getEtrUdpPortNumber(), is(UNIQUE_SHORT));
        assertThat(address.getMsUdpPortNumber(), is(UNIQUE_SHORT));
        // TODO: need to compare RtrRlocAddresses
    }

    @Test
    public void testNonceLcafAddressConversion() {
        LispNonceAddress address = (LispNonceAddress) ((ExtensionMappingAddressWrapper)
                getMappingAddressByAfiType(LCAF, NONCE)).extensionMappingAddress();
        assertThat(((IPMappingAddress) address.getAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
        assertThat(address.getNonce(), is(UNIQUE_INT));
    }

    @Test
    public void testMulticastLcafAddressConversion() {
        LispMulticastAddress address = (LispMulticastAddress) ((ExtensionMappingAddressWrapper)
                getMappingAddressByAfiType(LCAF, MULTICAST)).extensionMappingAddress();
        assertThat(((IPMappingAddress) address.getSrcAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
        assertThat(((IPMappingAddress) address.getGrpAddress()).ip(), is(IPV4_MAPPING_ADDRESS_1));
        assertThat(address.getInstanceId(), is(UNIQUE_INT));
        assertThat(address.getSrcMaskLength(), is(UNIQUE_BYTE));
        assertThat(address.getGrpMaskLength(), is(UNIQUE_BYTE));
    }

    @Test
    public void testSrcDstLcafAddressConversion() {
        LispSrcDstAddress address = (LispSrcDstAddress) ((ExtensionMappingAddressWrapper)
                getMappingAddressByAfiType(LCAF, SOURCE_DEST)).extensionMappingAddress();
        assertThat(((IPMappingAddress) address.getSrcPrefix()).ip(), is(IPV4_MAPPING_ADDRESS_1));
        assertThat(((IPMappingAddress) address.getDstPrefix()).ip(), is(IPV4_MAPPING_ADDRESS_2));
        assertThat(address.getSrcMaskLength(), is(UNIQUE_BYTE));
        assertThat(address.getDstMaskLength(), is(UNIQUE_BYTE));
    }

    @Test
    public void testTeLcafAddressConversion() {
        // TODO: need to compare TeRecord list
    }

    private MappingAddress getMappingAddressByAfiType(AddressFamilyIdentifierEnum afiType,
                                                      LispCanonicalAddressFormatEnum lcafType) {
        LispMapRecord record = getMapRecord(afiType, lcafType);
        MappingEntry entry = new MappingEntryBuilder(DEVICE_ID, record).build();
        return entry.value().treatments().get(0).address();
    }

    private void testMapRecordConversion(LispMapRecord record) {
        MappingEntry mappingEntry =
                     new MappingEntryBuilder(DEVICE_ID, record).build();
        MappingKey key = mappingEntry.key();
        MappingValue value = mappingEntry.value();

        IPMappingAddress recordAddress = (IPMappingAddress) key.address();

        assertThat(recordAddress.ip(), is(IpPrefix.valueOf(IP_RECORD_ADDRESS + "/" +
                IP_RECORD_MASK_LENGTH)));

        assertThat(value.action().type(), is(MappingAction.Type.NATIVE_FORWARD));

        assertThat(value.treatments().size(), is(1));

        MappingTreatment treatment = value.treatments().get(0);
        IPMappingAddress locatorAddress = (IPMappingAddress) treatment.address();

        assertThat(locatorAddress.ip(), is(IpPrefix.valueOf(IPV4_ADDRESS_1 + "/" +
                IP_LOCATOR_MASK_LENGTH)));
    }

    /**
     * Obtains a MapRecord instance.
     *
     * @param afiType   AFI address type
     * @param lcafType  LCAF address type
     * @return a MapRecord instance
     */
    private LispMapRecord getMapRecord(AddressFamilyIdentifierEnum afiType,
                                       LispCanonicalAddressFormatEnum lcafType) {
        MapRecordBuilder recordBuilder = new DefaultMapRecordBuilder();

        LispIpv4Address recordAddress =
                        new LispIpv4Address(IpAddress.valueOf(IP_RECORD_ADDRESS));

        LocatorBuilder locatorBuilder = new DefaultLocatorBuilder();

        LispAfiAddress locatorAddress = getAfiAddress(afiType, lcafType);

        LispLocator locator = locatorBuilder
                                    .withPriority(UNIQUE_BYTE)
                                    .withWeight(UNIQUE_BYTE)
                                    .withMulticastPriority(UNIQUE_BYTE)
                                    .withMulticastWeight(UNIQUE_BYTE)
                                    .withLocalLocator(true)
                                    .withRlocProbed(false)
                                    .withRouted(true)
                                    .withLocatorAfi(locatorAddress)
                                    .build();

        return recordBuilder
                .withRecordTtl(UNIQUE_INT)
                .withIsAuthoritative(true)
                .withMapVersionNumber(UNIQUE_SHORT)
                .withMaskLength((byte) IP_RECORD_MASK_LENGTH)
                .withAction(LispMapReplyAction.NativelyForward)
                .withEidPrefixAfi(recordAddress)
                .withLocators(ImmutableList.of(locator))
                .build();
    }

    /**
     * Obtains the AFI address with respect to the AFI address type.
     *
     * @param afiType   AFI address type
     * @param lcafType  LCAF address type
     * @return AFI address instance
     */
    private LispAfiAddress getAfiAddress(AddressFamilyIdentifierEnum afiType,
                                         LispCanonicalAddressFormatEnum lcafType) {
        switch (afiType) {
            case IP4:
                return IPV4_ADDRESS_1;
            case IP6:
                return IPV6_ADDRESS;
            case AS:
                return new LispAsAddress(UNIQUE_INT);
            case DISTINGUISHED_NAME:
                return new LispDistinguishedNameAddress(UNIQUE_STRING);
            case MAC:
                return MAC_ADDRESS;
            case LCAF:
                return getLcafAddress(lcafType);
            default:
                return null;
        }
    }

    /**
     * Obtains the LCAF address with respect to the LCAF type.
     *
     * @param type LCAF type
     * @return LCAF address instance
     */
    private LispLcafAddress getLcafAddress(LispCanonicalAddressFormatEnum type) {

        List<LispAfiAddress> afiAddresses =
                                    ImmutableList.of(IPV4_ADDRESS_1, IPV6_ADDRESS);

        switch (type) {
            case LIST:
                return new LispListLcafAddress(afiAddresses);
            case SEGMENT:
                return new LispSegmentLcafAddress.SegmentAddressBuilder()
                                    .withIdMaskLength(UNIQUE_BYTE)
                                    .withInstanceId(UNIQUE_INT)
                                    .withAddress(IPV4_ADDRESS_1)
                                    .build();
            case AS:
                return new LispAsLcafAddress.AsAddressBuilder()
                                    .withAsNumber(UNIQUE_INT)
                                    .withAddress(IPV4_ADDRESS_1)
                                    .build();
            case APPLICATION_DATA:
                return new LispAppDataLcafAddress.AppDataAddressBuilder()
                                    .withProtocol(UNIQUE_BYTE)
                                    .withIpTos(UNIQUE_SHORT)
                                    .withLocalPortLow(UNIQUE_SHORT)
                                    .withLocalPortHigh(UNIQUE_SHORT)
                                    .withRemotePortLow(UNIQUE_SHORT)
                                    .withRemotePortHigh(UNIQUE_SHORT)
                                    .withAddress(IPV4_ADDRESS_1)
                                    .build();
            case GEO_COORDINATE:
                return new LispGeoCoordinateLcafAddress.GeoCoordinateAddressBuilder()
                                    .withIsNorth(UNIQUE_BOOLEAN)
                                    .withLatitudeDegree(UNIQUE_SHORT)
                                    .withLatitudeMinute(UNIQUE_BYTE)
                                    .withLatitudeSecond(UNIQUE_BYTE)
                                    .withIsEast(UNIQUE_BOOLEAN)
                                    .withLongitudeDegree(UNIQUE_SHORT)
                                    .withLongitudeMinute(UNIQUE_BYTE)
                                    .withLongitudeSecond(UNIQUE_BYTE)
                                    .withAltitude(UNIQUE_INT)
                                    .withAddress(IPV4_ADDRESS_1)
                                    .build();
            case NAT:
                return new LispNatLcafAddress.NatAddressBuilder()
                                    .withLength(UNIQUE_SHORT)
                                    .withMsUdpPortNumber(UNIQUE_SHORT)
                                    .withEtrUdpPortNumber(UNIQUE_SHORT)
                                    .withGlobalEtrRlocAddress(IPV4_ADDRESS_1)
                                    .withMsRlocAddress(IPV4_ADDRESS_1)
                                    .withPrivateEtrRlocAddress(IPV4_ADDRESS_1)
                                    .withRtrRlocAddresses(afiAddresses)
                                    .build();
            case NONCE:
                return new LispNonceLcafAddress.NonceAddressBuilder()
                                    .withNonce(UNIQUE_INT)
                                    .withAddress(IPV4_ADDRESS_1)
                                    .build();
            case MULTICAST:
                return new LispMulticastLcafAddress.MulticastAddressBuilder()
                                    .withInstanceId(UNIQUE_INT)
                                    .withSrcMaskLength(UNIQUE_BYTE)
                                    .withGrpMaskLength(UNIQUE_BYTE)
                                    .withSrcAddress(IPV4_ADDRESS_1)
                                    .withGrpAddress(IPV4_ADDRESS_1)
                                    .build();
            case TRAFFIC_ENGINEERING:
                LispTeRecord.TeRecordBuilder recordBuilder1 = new LispTeRecord.TeRecordBuilder();

                recordBuilder1.withIsLookup(UNIQUE_BOOLEAN);
                recordBuilder1.withIsRlocProbe(UNIQUE_BOOLEAN);
                recordBuilder1.withIsStrict(UNIQUE_BOOLEAN);
                recordBuilder1.withRtrRlocAddress(IPV4_ADDRESS_1);
                LispTeRecord record1 = recordBuilder1.build();

                LispTeRecord.TeRecordBuilder recordBuilder2 = new LispTeRecord.TeRecordBuilder();

                recordBuilder2.withIsLookup(UNIQUE_BOOLEAN);
                recordBuilder2.withIsRlocProbe(UNIQUE_BOOLEAN);
                recordBuilder2.withIsStrict(UNIQUE_BOOLEAN);
                recordBuilder2.withRtrRlocAddress(IPV4_ADDRESS_2);
                LispTeRecord record2 = recordBuilder2.build();

                return new LispTeLcafAddress.TeAddressBuilder()
                                    .withTeRecords(ImmutableList.of(record1, record2))
                                    .build();
            case SOURCE_DEST:
                return new LispSourceDestLcafAddress.SourceDestAddressBuilder()
                                    .withReserved(UNIQUE_SHORT)
                                    .withSrcMaskLength(UNIQUE_BYTE)
                                    .withDstMaskLength(UNIQUE_BYTE)
                                    .withSrcPrefix(IPV4_ADDRESS_1)
                                    .withDstPrefix(IPV4_ADDRESS_2)
                                    .build();
            case UNKNOWN:
            case UNSPECIFIED:
            default:
                return null;
        }
    }
}
