/*
 * Copyright 2016-present Open Networking Foundation
 *
 * 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.area;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.google.common.base.MoreObjects;
import com.google.common.base.Objects;
import org.onlab.packet.Ip4Address;
import org.onosproject.ospf.controller.LsaWrapper;
import org.onosproject.ospf.controller.OspfArea;
import org.onosproject.ospf.controller.OspfInterface;
import org.onosproject.ospf.controller.OspfLsa;
import org.onosproject.ospf.controller.OspfLsaType;
import org.onosproject.ospf.controller.OspfLsdb;
import org.onosproject.ospf.controller.OspfNbr;
import org.onosproject.ospf.controller.OspfNeighborState;
import org.onosproject.ospf.controller.impl.OspfNbrImpl;
import org.onosproject.ospf.controller.lsdb.OspfLsdbImpl;
import org.onosproject.ospf.exceptions.OspfParseException;
import org.onosproject.ospf.protocol.lsa.LsaHeader;
import org.onosproject.ospf.protocol.lsa.subtypes.OspfLsaLink;
import org.onosproject.ospf.protocol.lsa.types.NetworkLsa;
import org.onosproject.ospf.protocol.lsa.types.RouterLsa;
import org.onosproject.ospf.protocol.util.ChecksumCalculator;
import org.onosproject.ospf.protocol.util.OspfInterfaceState;
import org.onosproject.ospf.protocol.util.OspfParameters;
import org.onosproject.ospf.protocol.util.OspfUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * Representation an OSPF area and related information.
 */
public class OspfAreaImpl implements OspfArea {
    private static final Logger log = LoggerFactory.getLogger(OspfAreaImpl.class);
    /**
     * Whether AS-external-LSAs will be flooded into/throughout the area.
     */
    private boolean externalRoutingCapability;

    /**
     * Represents a list of all router's interfaces associated with this area.
     */
    private List<OspfInterface> ospfInterfaceList;
    /**
     * The LS Database for this area. It includes router-LSAs, network-LSAs and.
     * summary-LSAs. AS-external-LSAs are hold in the OSPF class itself.
     */
    private OspfLsdbImpl database;
    /**
     * A 32-bit number identifying the area.
     */
    private Ip4Address areaId;
    /**
     * Router ID.
     */
    private Ip4Address routerId;
    /**
     * Represents Options like external, opaque capabilities.
     */
    private int options;
    /**
     * Represents Opaque Enable or not.
     */
    private boolean isOpaqueEnable;

    /**
     * Creates an instance of area implementation.
     */
    public OspfAreaImpl() {
        database = new OspfLsdbImpl(this);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        OspfAreaImpl that = (OspfAreaImpl) o;
        return Objects.equal(areaId, that.areaId) &&
                Objects.equal(routerId, that.routerId) &&
                Objects.equal(externalRoutingCapability, that.externalRoutingCapability) &&
                Objects.equal(ospfInterfaceList.size(), that.ospfInterfaceList.size()) &&
                Objects.equal(database, that.database);
    }

    @Override
    public int hashCode() {
        return Objects.hashCode(areaId, routerId, externalRoutingCapability,
                                ospfInterfaceList, database);
    }

    /**
     * Gets the router id.
     *
     * @return router id
     */
    public Ip4Address routerId() {
        return routerId;
    }

    /**
     * Sets the router id.
     *
     * @param routerId router id
     */
    @JsonProperty("routerId")
    public void setRouterId(Ip4Address routerId) {
        this.routerId = routerId;
    }

    /**
     * Sets opaque enabled to true or false.
     *
     * @param isOpaqueEnable true if opaque enabled else false
     */
    @JsonProperty("isOpaqueEnable")
    public void setIsOpaqueEnabled(boolean isOpaqueEnable) {
        this.isOpaqueEnable = isOpaqueEnable;
    }

    /**
     * Gets is opaque enabled or not.
     *
     * @return true if opaque enabled else false
     */
    public boolean isOpaqueEnabled() {
        return this.isOpaqueEnable;
    }

    /**
     * Initializes link state database.
     */
    public void initializeDb() {

        database.initializeDb();
    }

    /**
     * Refreshes the OSPF area information .
     * Gets called as soon as the interface is down or neighbor full Router LSA is updated.
     *
     * @param ospfInterface OSPF interface instance
     */
    @Override
    public void refreshArea(OspfInterface ospfInterface) {
        OspfInterfaceImpl ospfInterfaceImpl = (OspfInterfaceImpl) ospfInterface;
        log.debug("Inside refreshArea...!!!");
        //If interface state is DR build network LSA.
        if (ospfInterfaceImpl.state() == OspfInterfaceState.DR) {
            if (ospfInterface.listOfNeighbors().size() > 0) {
                //Get the NetworkLsa
                NetworkLsa networkLsa = null;
                try {
                    networkLsa = buildNetworkLsa(ospfInterface.ipAddress(), ospfInterface.ipNetworkMask());
                } catch (Exception e) {
                    log.debug("Error while building NetworkLsa {}", e.getMessage());
                }
                //Add the NetworkLsa to lsdb
                database.addLsa(networkLsa, true, ospfInterface);
                addToOtherNeighborLsaTxList(networkLsa);
            } else {
                log.debug("No Neighbors hence not creating  NetworkLSA...!!!");
            }
        }
        //Get the router LSA
        RouterLsa routerLsa = null;
        try {
            routerLsa = buildRouterLsa(ospfInterface);
        } catch (Exception e) {
            log.debug("Error while building RouterLsa {}", e.getMessage());
        }
        //Add the RouterLSA to lsdb
        database.addLsa(routerLsa, true, ospfInterface);
        addToOtherNeighborLsaTxList(routerLsa);
    }

    /**
     * Builds a network LSA.
     *
     * @param interfaceIp interface IP address
     * @param mask        interface network mask
     * @return NetworkLsa instance
     * @throws OspfParseException might throws exception
     */
    public NetworkLsa buildNetworkLsa(Ip4Address interfaceIp, Ip4Address mask) throws OspfParseException {
        // generate the Router-LSA for this Area.
        NetworkLsa networkLsa = new NetworkLsa();
        networkLsa.setAdvertisingRouter(routerId);
        networkLsa.setLinkStateId(interfaceIp.toString());
        networkLsa.setLsType(OspfLsaType.NETWORK.value());
        networkLsa.setAge(1);
        networkLsa.setOptions(2);
        networkLsa.setNetworkMask(mask);
        //Adding our own router.
        networkLsa.addAttachedRouter(routerId());
        Iterator iter = ospfInterfaceList.iterator();
        OspfInterfaceImpl ospfInterface = null;
        while (iter.hasNext()) {
            ospfInterface = (OspfInterfaceImpl) iter.next();
            if (ospfInterface.ipAddress().equals(interfaceIp)) {
                break;
            }
        }
        if (ospfInterface != null) {
            List<OspfNbr> neighborsInFullState = getNeighborsInFullState(ospfInterface);
            if (neighborsInFullState != null) {
                for (OspfNbr ospfnbr : neighborsInFullState) {
                    networkLsa.addAttachedRouter(ospfnbr.neighborId());
                    log.debug("Adding attached neighbor:: {}", ospfnbr.neighborId());
                }
            }
        }
        networkLsa.setLsSequenceNo(database.getLsSequenceNumber(OspfLsaType.NETWORK));
        //Find the byte length and add it in lsa object
        ChecksumCalculator checksum = new ChecksumCalculator();
        byte[] lsaBytes = networkLsa.asBytes();
        networkLsa.setLsPacketLen(lsaBytes.length);
        //Convert lsa object to byte again to reflect the packet length which we added.
        lsaBytes = networkLsa.asBytes();
        //find the checksum
        byte[] twoByteChecksum = checksum.calculateLsaChecksum(lsaBytes,
                                                               OspfUtil.LSAPACKET_CHECKSUM_POS1,
                                                               OspfUtil.LSAPACKET_CHECKSUM_POS2);
        int checkSumVal = OspfUtil.byteToInteger(twoByteChecksum);
        networkLsa.setLsCheckSum(checkSumVal);
        return networkLsa;
    }

    /**
     * Builds Router LSA.
     *
     * @param ospfInterface Interface instance
     * @return routerLsa Router LSA instance
     * @throws OspfParseException might throws exception
     */
    public RouterLsa buildRouterLsa(OspfInterface ospfInterface) throws OspfParseException {
        // generate the Router-LSA for this Area.
        RouterLsa routerLsa = new RouterLsa();
        routerLsa.setAdvertisingRouter(routerId);
        routerLsa.setLinkStateId(routerId.toString());
        routerLsa.setLsType(OspfLsaType.ROUTER.value());
        routerLsa.setAge(1);
        routerLsa.setOptions(options);
        routerLsa.setAreaBorderRouter(false);
        routerLsa.setAsBoundaryRouter(false);
        routerLsa.setVirtualEndPoint(false);
        buildLinkForRouterLsa(routerLsa, ospfInterface);
        routerLsa.setLsSequenceNo(database.getLsSequenceNumber(OspfLsaType.ROUTER));
        //Find the byte length and add it in lsa object
        ChecksumCalculator checksum = new ChecksumCalculator();
        byte[] lsaBytes = routerLsa.asBytes();
        routerLsa.setLsPacketLen(lsaBytes.length);
        //Convert lsa object to byte again to reflect the packet length which we added.
        lsaBytes = routerLsa.asBytes();
        //find the checksum
        byte[] twoByteChecksum = checksum.calculateLsaChecksum(lsaBytes,
                                                               OspfUtil.LSAPACKET_CHECKSUM_POS1,
                                                               OspfUtil.LSAPACKET_CHECKSUM_POS2);
        int checkSumVal = OspfUtil.byteToInteger(twoByteChecksum);
        routerLsa.setLsCheckSum(checkSumVal);
        return routerLsa;
    }

    /**
     * Builds LSA link for router LSA.
     *
     * @param routerLsa     router LSA instance
     * @param ospfInterface interface instance
     */
    private void buildLinkForRouterLsa(RouterLsa routerLsa, OspfInterface ospfInterface) {
        OspfInterfaceImpl nextInterface;
        Iterator interfaces = ospfInterfaceList.iterator();
        while (interfaces.hasNext()) {
            nextInterface = (OspfInterfaceImpl) interfaces.next();
            if (nextInterface.state() == OspfInterfaceState.DOWN) {
                continue;
            } else if (nextInterface.state() == OspfInterfaceState.LOOPBACK) {
                OspfLsaLink link = new OspfLsaLink();
                link.setLinkData("-1");
                link.setLinkId(nextInterface.ipAddress().toString());
                link.setLinkType(3);
                link.setMetric(0);
                link.setTos(0);
                routerLsa.addRouterLink(link);
                routerLsa.incrementLinkNo();
            } else if (nextInterface.state() == OspfInterfaceState.POINT2POINT) {
                // adding all neighbour routers
                List<OspfNbr> neighborsInFullState = getNeighborsInFullState(nextInterface);
                if (neighborsInFullState != null) {
                    log.debug("Adding OspfLsaLink ::neighborsInFullState {}, InterfaceIP: {}",
                              neighborsInFullState.size(), nextInterface.ipAddress());
                    for (OspfNbr ospfnbr : neighborsInFullState) {
                        OspfLsaLink link = new OspfLsaLink();
                        link.setLinkData(nextInterface.ipAddress().toString());
                        link.setLinkId(ospfnbr.neighborId().toString());
                        link.setLinkType(1);
                        link.setMetric(0);
                        link.setTos(0);
                        routerLsa.addRouterLink(link);
                        routerLsa.incrementLinkNo();
                        log.debug("Added OspfLsaLink :: {}, neighborIP: {}, routerLinks: {}",
                                  ospfnbr.neighborId(), ospfnbr.neighborIpAddr(), routerLsa.noLink());
                    }
                }
                // adding the self address
                OspfLsaLink link = new OspfLsaLink();
                link.setLinkData(nextInterface.ipNetworkMask().toString());
                link.setLinkId(nextInterface.ipAddress().toString());
                link.setLinkType(3);
                link.setMetric(0);
                link.setTos(0);
                routerLsa.addRouterLink(link);
                routerLsa.incrementLinkNo();
            } else {
                buildLinkForRouterLsaBroadcast(routerLsa, nextInterface);
            }
        }
    }

    /**
     * Builds LSA link for router LSA.
     *
     * @param routerLsa     router LSA instance
     * @param ospfInterface interface instance
     */
    private void buildLinkForRouterLsaBroadcast(RouterLsa routerLsa, OspfInterface ospfInterface) {
        OspfInterfaceImpl ospfInterfaceImpl = (OspfInterfaceImpl) ospfInterface;
        if (ospfInterfaceImpl.state() == OspfInterfaceState.WAITING) {
            OspfLsaLink link = new OspfLsaLink();
            link.setLinkData(ospfInterface.ipNetworkMask().toString());
            //Link id should be set to ip network number
            link.setLinkId(ospfInterface.ipAddress().toString());
            link.setLinkType(3);
            link.setMetric(0);
            link.setTos(0);
            routerLsa.addRouterLink(link);
            routerLsa.incrementLinkNo();
        } else if (ospfInterfaceImpl.state() == OspfInterfaceState.DR) {
            OspfLsaLink link = new OspfLsaLink();
            link.setLinkData(ospfInterface.ipAddress().toString());
            link.setLinkId(ospfInterface.ipAddress().toString());
            link.setLinkType(2);
            link.setMetric(0);
            link.setTos(0);
            routerLsa.addRouterLink(link);
            routerLsa.incrementLinkNo();
        } else if (ospfInterfaceImpl.state() == OspfInterfaceState.BDR ||
                ospfInterfaceImpl.state() == OspfInterfaceState.DROTHER) {
            OspfLsaLink link = new OspfLsaLink();
            link.setLinkData(ospfInterface.ipAddress().toString());
            link.setLinkId(ospfInterface.dr().toString());
            link.setLinkType(2);
            link.setMetric(0);
            link.setTos(0);
            routerLsa.addRouterLink(link);
            routerLsa.incrementLinkNo();
        }
    }

    /**
     * Gets the area id.
     *
     * @return area id
     */
    public Ip4Address areaId() {
        return areaId;
    }

    /**
     * Sets the area id.
     *
     * @param areaId area id
     */
    @JsonProperty("areaId")
    public void setAreaId(Ip4Address areaId) {
        this.areaId = areaId;
    }

    /**
     * Gets external routing capability.
     *
     * @return true if external routing capable, else false
     */
    public boolean isExternalRoutingCapability() {
        return externalRoutingCapability;
    }

    /**
     * Sets external routing capability.
     *
     * @param externalRoutingCapability true if external routing capable, else false
     */
    @JsonProperty("externalRoutingCapability")
    public void setExternalRoutingCapability(boolean externalRoutingCapability) {
        this.externalRoutingCapability = externalRoutingCapability;
    }

    /**
     * Gets the list of interfaces in this area.
     *
     * @return list of interfaces
     */
    public List<OspfInterface> ospfInterfaceList() {
        return ospfInterfaceList;
    }

    /**
     * Sets the list of interfaces attached to the area.
     *
     * @param ospfInterfaceList list of OspfInterface instances
     */
    @JsonProperty("interface")
    public void setOspfInterfaceList(List<OspfInterface> ospfInterfaceList) {
        this.ospfInterfaceList = ospfInterfaceList;
    }

    /**
     * Checks all neighbors belonging to this area whether they are in state EXCHANGE or LOADING.
     * Return false if there is at least one, else return true. This Method is used by
     * "processReceivedLsa()" in the neighbor class.
     *
     * @return boolean indicating that there is no Neighbor in Database Exchange
     */
    public boolean noNeighborInLsaExchangeProcess() {
        OspfInterfaceImpl nextInterface;
        OspfNeighborState nextNeighborState;
        Iterator interfaces = ospfInterfaceList.iterator();
        while (interfaces.hasNext()) {
            nextInterface = (OspfInterfaceImpl) interfaces.next();
            Iterator neighbors = nextInterface.listOfNeighbors().values().iterator();
            while (neighbors.hasNext()) {
                nextNeighborState = ((OspfNbrImpl) neighbors.next()).getState();
                if (nextNeighborState == OspfNeighborState.EXCHANGE ||
                        nextNeighborState == OspfNeighborState.LOADING) {
                    return false;
                }
            }
        }
        return true;
    }

    /**
     * Gets header of all types of LSAs.
     *
     * @param excludeMaxAgeLsa need to include(true) or exclude(false) maxage lsa's
     * @param isOpaquecapable  need to include(true) or exclude(false) Type 10 Opaque lsa's
     * @return list of lsa header in the lsdb
     */
    public List getLsaHeaders(boolean excludeMaxAgeLsa, boolean isOpaquecapable) {
        return database.getAllLsaHeaders(excludeMaxAgeLsa, isOpaquecapable);
    }

    /**
     * Gets the LSA from LSDB based on the input.
     *
     * @param lsType            type of lsa to form the key
     * @param linkStateID       link state id to form the key
     * @param advertisingRouter advertising router to form the key
     * @return lsa wrapper instance which contains the Lsa
     */
    public LsaWrapper getLsa(int lsType, String linkStateID, String advertisingRouter) {
        String lsaKey = lsType + "-" + linkStateID + "-" + advertisingRouter;
        if (lsType == OspfParameters.LINK_LOCAL_OPAQUE_LSA || lsType == OspfParameters.AREA_LOCAL_OPAQUE_LSA ||
                lsType == OspfParameters.AS_OPAQUE_LSA) {
            try {
                byte[] linkStateAsBytes = InetAddress.getByName(linkStateID).getAddress();

                int opaqueType = linkStateAsBytes[0];
                int opaqueId = OspfUtil.byteToInteger(Arrays.copyOfRange(linkStateAsBytes, 1,
                                                                     linkStateAsBytes.length));
                lsaKey = lsType + "-" + opaqueType + opaqueId + "-" + advertisingRouter;
            } catch (UnknownHostException uhe) {
                log.warn("Can't resolve host in Lsa wrapper", uhe);
                return null;
            }
        }
        return database.findLsa(lsType, lsaKey);
    }


    /**
     * Checks whether an instance of the given LSA exists in the database belonging to this area.
     * If so return true else false.
     *
     * @param lookupLsa ospf LSA instance to lookup
     * @return LSA wrapper instance which contains the Lsa
     */
    public LsaWrapper lsaLookup(OspfLsa lookupLsa) {
        return database.lsaLookup((LsaHeader) lookupLsa);
    }

    /**
     * Checks whether an instance of the given LSA exists in the database belonging to this area.
     * If so return true else false.
     *
     * @param lsa1 OSPF LSA instance to compare
     * @param lsa2 OSPF LSA instance to compare
     * @return "same" if both instances are same, "latest" if lsa1 is latest, or "old" if lsa1 is old
     */
    public String isNewerOrSameLsa(OspfLsa lsa1, OspfLsa lsa2) {
        return database.isNewerOrSameLsa((LsaHeader) lsa1, (LsaHeader) lsa2);
    }

    /**
     * Methods gets called from ChannelHandler to add the received LSA to LSDB.
     *
     * @param ospfLsa       OSPF LSA instance
     * @param ospfInterface OSPF interface instance
     */
    public void addLsa(OspfLsa ospfLsa, OspfInterface ospfInterface) {
        //second param is false as lsa from network
        database.addLsa((LsaHeader) ospfLsa, false, ospfInterface);
    }

    /**
     * Methods gets called from ChannelHandler to add the received LSA to LSDB.
     *
     * @param ospfLsa          OSPF LSA instance
     * @param isSelfOriginated true if the LSA is self originated. Else false
     * @param ospfInterface    OSPF interface instance
     */
    public void addLsa(OspfLsa ospfLsa, boolean isSelfOriginated, OspfInterface ospfInterface) {
        database.addLsa((LsaHeader) ospfLsa, isSelfOriginated, ospfInterface);
    }

    /**
     * Adds the LSA to maxAge bin.
     *
     * @param key     key to add it to LSDB
     * @param wrapper LSA wrapper instance
     */
    public void addLsaToMaxAgeBin(String key, LsaWrapper wrapper) {
        database.addLsaToMaxAgeBin(key, wrapper);
    }

    /**
     * Sets router sequence number for router LSA.
     *
     * @param newSequenceNumber sequence number
     */
    public void setDbRouterSequenceNumber(long newSequenceNumber) {
        database.setRouterLsaSeqNo(newSequenceNumber);
    }

    /**
     * Methods gets called from ChannelHandler to delete the LSA.
     *
     * @param ospfLsa the LSA instance to delete
     */
    public void deleteLsa(LsaHeader ospfLsa) {
        database.deleteLsa(ospfLsa);
    }

    /**
     * Removes LSA from bin.
     *
     * @param lsaWrapper the LSA wrapper instance to delete
     */
    public void removeLsaFromBin(LsaWrapper lsaWrapper) {
        database.removeLsaFromBin(lsaWrapper);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .omitNullValues()
                .add("areaID", areaId)
                .add("ospfInterfaceList", ospfInterfaceList)
                .add("externalRoutingCapability", externalRoutingCapability)
                .toString();
    }

    /**
     * Checks all Neighbors belonging to this Area whether they are in state lesser than the EXCHANGE.
     * Creates list of such neighbors
     * Returns list of neighbors who satisfy the conditions
     *
     * @param ospfInterface OSPF interface instance
     * @return List of interfaces having state lesser than exchange
     */
    public List<OspfNbr> getNeighborsInFullState(OspfInterface ospfInterface) {

        List<OspfNbr> listEligibleNeighbors = null;
        OspfNbrImpl ospfNeighbor = null;
        OspfNeighborState nextNeighborState;
        Iterator nbrInterface = ospfInterface.listOfNeighbors().values().iterator();
        while (nbrInterface.hasNext()) {
            ospfNeighbor = (OspfNbrImpl) nbrInterface.next();
            nextNeighborState = ospfNeighbor.getState();
            if (nextNeighborState.getValue() == OspfNeighborState.FULL.getValue()) {
                if (listEligibleNeighbors == null) {
                    listEligibleNeighbors = new ArrayList<OspfNbr>();
                    listEligibleNeighbors.add(ospfNeighbor);
                } else {
                    listEligibleNeighbors.add(ospfNeighbor);
                }
            }
        }
        return listEligibleNeighbors;
    }

    /**
     * Gets the LSDB LSA key from LSA header.
     *
     * @param lsaHeader LSA header instance
     * @return key LSA key
     */
    public String getLsaKey(LsaHeader lsaHeader) {
        return database.getLsaKey(lsaHeader);
    }

    /**
     * Adds the received LSA in other neighbors tx list.
     *
     * @param recLsa LSA Header instance
     */
    public void addToOtherNeighborLsaTxList(LsaHeader recLsa) {
        //Add the received LSA in other neighbors retransmission list.
        log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList");
        List<OspfInterface> ospfInterfaces = ospfInterfaceList();
        for (OspfInterface ospfInterfaceFromArea : ospfInterfaces) {
            Map neighbors = ospfInterfaceFromArea.listOfNeighbors();
            for (Object neighborIP : neighbors.keySet()) {
                OspfNbrImpl nbr = (OspfNbrImpl) neighbors.get(neighborIP);
                if (nbr.getState().getValue() < OspfNeighborState.EXCHANGE.getValue()) {
                    continue;
                }
                String key = database.getLsaKey(recLsa);
                if (nbr.getState() == OspfNeighborState.EXCHANGE || nbr.getState() == OspfNeighborState.LOADING) {
                    if (nbr.getLsReqList().containsKey(key)) {
                        LsaWrapper lsWrapper = lsaLookup(recLsa);
                        if (lsWrapper != null) {
                            LsaHeader ownLsa = (LsaHeader) lsWrapper.ospfLsa();
                            String status = isNewerOrSameLsa(recLsa, ownLsa);
                            if (status.equals("old")) {
                                continue;
                            } else if (status.equals("same")) {
                                log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: " +
                                                  "Removing lsa from reTxtList {}", key);
                                nbr.getLsReqList().remove(key);
                                continue;
                            } else {
                                log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: " +
                                                  "Removing lsa from reTxtList {}", key);
                                nbr.getLsReqList().remove(key);
                            }
                        }
                    }
                }
                if (recLsa.advertisingRouter().toString().equals((String) neighborIP)) {
                    continue;
                }
                if ((recLsa.lsType() == OspfParameters.LINK_LOCAL_OPAQUE_LSA ||
                        recLsa.lsType() == OspfParameters.AREA_LOCAL_OPAQUE_LSA)) {
                    if (nbr.isOpaqueCapable()) {
                        log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: Adding lsa to reTxtList {}",
                                  recLsa);
                        nbr.getReTxList().put(key, recLsa);
                    }
                } else {
                    log.debug("OspfAreaImpl: addToOtherNeighborLsaTxList: Adding lsa to reTxtList {}",
                              recLsa);
                    nbr.getReTxList().put(key, recLsa);
                }
            }
        }
    }

    /**
     * Gets the options value.
     *
     * @return options value
     */
    public int options() {
        return options;
    }

    /**
     * Sets the options value.
     *
     * @param options options value
     */
    public void setOptions(int options) {
        this.options = options;
    }

    /**
     * Gets the opaque enabled options value.
     *
     * @return opaque enabled options value
     */
    public int opaqueEnabledOptions() {
        return Integer.parseInt(OspfParameters.OPAQUE_ENABLED_OPTION_VALUE, 2);
    }

    /**
     * Gets the lsdb instance for this area.
     *
     * @return lsdb instance
     */
    public OspfLsdb database() {
        return database;
    }
}
