/*
 * 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;

import org.onlab.packet.Ip4Address;

import java.util.List;

/**
 * Representation of an OSPF area. OSPF areas are collections of network segments.
 * The configuration of OSPF area consists of assigning an area id to each network segment.
 * Each area has its own link state database.
 */
public interface OspfArea {

    /**
     * Gets the router id associated with the area.
     *
     * @return router id
     */
    Ip4Address routerId();

    /**
     * Sets the router id for this area.
     *
     * @param routerId router's ip address
     */
    void setRouterId(Ip4Address routerId);

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

    /**
     * Sets the area id.
     *
     * @param areaId area id as an IPv4 address
     */
    void setAreaId(Ip4Address areaId);

    /**
     * Gets the LSDB instance for this area.
     *
     * @return LSDB instance for this area
     */
    OspfLsdb database();

    /**
     * Checks whether an instance of the given LSA exists in the database.
     *
     * @param lookupLsa LSA instance to lookup
     * @return LSA wrapper instance which contains the LSA
     */
    LsaWrapper lsaLookup(OspfLsa lookupLsa);

    /**
     * Initializes link state database, this acts as a place holder for storing the received LSA.
     */
    void initializeDb();

    /**
     * Sets the options value.
     *
     * @param options integer value
     */
    void setOptions(int options);

    /**
     * Gets external routing capability.
     * This indicates Whether AS-external-LSAs will be flooded into/throughout the area.
     *
     * @return true if external routing capable, else false
     */
    boolean isExternalRoutingCapability();

    /**
     * Sets external routing capability.
     * This indicates Whether AS-external-LSAs will be flooded into/throughout the area.
     *
     * @param externalRoutingCapability true if external routing capable, else false
     */
    void setExternalRoutingCapability(boolean externalRoutingCapability);

    /**
     * Gets if the router is opaque enabled or not.
     * This indicates whether the router accepts opaque LSA.
     *
     * @return true if opaque enabled else false
     */
    boolean isOpaqueEnabled();

    /**
     * Gets the list of interfaces attached to this area.
     *
     * @return list of interfaces
     */
    List<OspfInterface> ospfInterfaceList();

    /**
     * Sets the list of interfaces attached to this area.
     *
     * @param interfacesLst list of interface instances
     */
    void setOspfInterfaceList(List<OspfInterface> interfacesLst);

    /**
     * Gets the options value, which indicates the supported optional capabilities.
     *
     * @return options value
     */
    int options();

    /**
     * Gets the opaque enabled options value, which indicates support of opaque capabilities.
     *
     * @return opaque enabled options value
     */
    int opaqueEnabledOptions();

    /**
     * Sets opaque enabled to true or false, which indicates whether the router accepts opaque LSA.
     *
     * @param isOpaqueEnable true if opaque enabled else false
     */
    void setIsOpaqueEnabled(boolean isOpaqueEnable);

    /**
     * Refreshes areas, by sending a router LSA and network LSA (in case of DR).
     * with a new sequence number.
     *
     * @param ospfInterface interface instance
     */
    void refreshArea(OspfInterface ospfInterface);

    /**
     * Verifies no neighbor is in exchange process.
     *
     * @return boolean indicating that there is no Neighbor in Database Exchange
     */
    boolean noNeighborInLsaExchangeProcess();

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

    /**
     * Whenever we receive an LSA with max age - we put it in the max age bin.
     * This is later used to flush LSAs out of the routing domain.
     *
     * @param key     key to add it to LSDB
     * @param wrapper LSA wrapper instance
     */
    void addLsaToMaxAgeBin(String key, LsaWrapper wrapper);

    /**
     * Whenever an LSA is being flushed out or reaches max age, it must be stopped from aging.
     * This achieved by removing it from bin.
     *
     * @param lsaWrapper the LSA wrapper instance to delete
     */
    void removeLsaFromBin(LsaWrapper lsaWrapper);

    /**
     * Adds the received LSA to LSDB, this method creates an LSA wrapper for the LSA.
     * Also adds it to the LSDB of the area. This method is specifically called for
     * the self originated LSAs.
     *
     * @param ospfLsa          LSA instance
     * @param isSelfOriginated true if the LSA is self originated else false
     * @param ospfInterface    interface instance
     */
    void addLsa(OspfLsa ospfLsa, boolean isSelfOriginated, OspfInterface ospfInterface);

    /**
     * Adds the received LSA to LSDB,this method creates an LSA wrapper for the LSA.
     * Adds it to the LSDB of the area.
     *
     * @param ospfLsa       LSA instance
     * @param ospfInterface interface instance
     */
    void addLsa(OspfLsa ospfLsa, OspfInterface ospfInterface);

    /**
     * Sets router sequence number for router LSA.
     *
     * @param newSequenceNumber sequence number
     */
    void setDbRouterSequenceNumber(long newSequenceNumber);

    /**
     * Gets LSA header of all types of LSAs present in the link state database.
     *
     * @param excludeMaxAgeLsa need to include(true) or exclude(false) max age LSA
     * @param isOpaqueCapable  need to include(true) or exclude(false) type 10 Opaque LSA
     * @return list of LSA header in the LSDB
     */
    List getLsaHeaders(boolean excludeMaxAgeLsa, boolean isOpaqueCapable);

    /**
     * Gets the LSA wrapper from link state database based on the parameters passed.
     *
     * @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
     */
    LsaWrapper getLsa(int lsType, String linkStateID, String advertisingRouter);

}