/*
 * 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.isis.controller.impl.lsdb;

import org.onosproject.isis.controller.IsisInterface;
import org.onosproject.isis.controller.IsisLsdb;
import org.onosproject.isis.controller.IsisLsdbAge;
import org.onosproject.isis.controller.IsisLspBin;
import org.onosproject.isis.controller.IsisMessage;
import org.onosproject.isis.controller.IsisPduType;
import org.onosproject.isis.controller.LspWrapper;
import org.onosproject.isis.io.isispacket.pdu.LsPdu;
import org.onosproject.isis.io.util.IsisConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * Representation of ISIS link state database.
 */
public class DefaultIsisLsdb implements IsisLsdb {
    private static final Logger log = LoggerFactory.getLogger(DefaultIsisLsdb.class);
    private Map<String, LspWrapper> isisL1Db = new ConcurrentHashMap<>();
    private Map<String, LspWrapper> isisL2Db = new ConcurrentHashMap<>();
    private IsisLsdbAge lsdbAge = null;
    private int l1LspSeqNo = IsisConstants.STARTLSSEQUENCENUM;
    private int l2LspSeqNo = IsisConstants.STARTLSSEQUENCENUM;

    /**
     * Creates an instance of ISIS LSDB.
     */
    public DefaultIsisLsdb() {
        lsdbAge = new DefaultIsisLsdbAge();
    }

    /**
     * Initializes the link state database.
     */
    public void initializeDb() {
        lsdbAge.startDbAging();
    }

    /**
     * Returns the LSDB LSP key.
     *
     * @param systemId system ID
     * @return key
     */
    public String lspKey(String systemId) {
        StringBuilder lspKey = new StringBuilder();
        lspKey.append(systemId);
        lspKey.append(".00");
        lspKey.append("-");
        lspKey.append("00");

        return lspKey.toString();
    }

    /**
     * Returns the neighbor L1 database information.
     *
     * @return neighbor L1 database information
     */
    public Map<String, LspWrapper> getL1Db() {
        return isisL1Db;
    }

    /**
     * Returns the neighbor L2 database information.
     *
     * @return neighbor L2 database information
     */
    public Map<String, LspWrapper> getL2Db() {
        return isisL2Db;
    }

    /**
     * Returns the LSDB instance.
     *
     * @return LSDB instance
     */
    public IsisLsdb isisLsdb() {
        return this;
    }

    /**
     * Returns all LSPs (L1 and L2).
     *
     * @param excludeMaxAgeLsp exclude the max age LSPs
     * @return List of LSPs
     */
    public List<LspWrapper> allLspHeaders(boolean excludeMaxAgeLsp) {
        List<LspWrapper> summaryList = new CopyOnWriteArrayList();
        addLspToHeaderList(summaryList, excludeMaxAgeLsp, isisL1Db);
        addLspToHeaderList(summaryList, excludeMaxAgeLsp, isisL2Db);

        return summaryList;
    }

    /**
     * Adds the LSPs to summary list.
     *
     * @param summaryList      summary list
     * @param excludeMaxAgeLsp exclude max age LSP
     * @param lspMap           map of LSP
     */
    private void addLspToHeaderList(List summaryList, boolean excludeMaxAgeLsp, Map lspMap) {
        Iterator slotVals = lspMap.values().iterator();
        while (slotVals.hasNext()) {
            LspWrapper wrapper = (LspWrapper) slotVals.next();
            if (excludeMaxAgeLsp) {
                //if current age of lsa is max age or lsa present in Max Age bin
                if (wrapper.remainingLifetime() != 0) {
                    addToList(wrapper, summaryList);
                }
            } else {
                addToList(wrapper, summaryList);
            }
        }
    }

    /**
     * Adds the LSPWrapper to summary list.
     *
     * @param wrapper  LSP wrapper instance
     * @param summList LSP summary list
     */
    private void addToList(LspWrapper wrapper, List summList) {
        //set the current age
        ((LsPdu) wrapper.lsPdu()).setRemainingLifeTime(wrapper.remainingLifetime());
        summList.add(wrapper);
    }

    /**
     * Finds the LSP from appropriate maps L1 or L2 based on type.
     *
     * @param pduType L1 or L2 LSP
     * @param lspId   LSP ID
     * @return LSP wrapper object
     */
    public LspWrapper findLsp(IsisPduType pduType, String lspId) {
        LspWrapper lspWrapper = null;

        switch (pduType) {
            case L1LSPDU:
                lspWrapper = isisL1Db.get(lspId);
                break;
            case L2LSPDU:
                lspWrapper = isisL2Db.get(lspId);
                break;
            default:
                log.debug("Unknown LSP type..!!!");
                break;
        }

        //set the current age
        if (lspWrapper != null) {
            //set the current age
            ((DefaultLspWrapper) lspWrapper).lsPdu().setRemainingLifeTime(lspWrapper.remainingLifetime());
        }

        return lspWrapper;
    }

    /**
     * Installs a new self-originated LSP.
     *
     * @return true if successfully added
     */
    public boolean addLsp(IsisMessage isisMessage, boolean isSelfOriginated, IsisInterface isisInterface) {
        LsPdu lspdu = (LsPdu) isisMessage;
        DefaultLspWrapper lspWrapper = new DefaultLspWrapper();
        lspWrapper.setLspAgeReceived(IsisConstants.LSPMAXAGE - lspdu.remainingLifeTime());
        lspWrapper.setRemainingLifetime(IsisConstants.LSPMAXAGE - lsdbAge.ageCounter());
        lspWrapper.setLspType(IsisPduType.get(lspdu.pduType()));
        lspWrapper.setLsPdu(lspdu);
        lspWrapper.setAgeCounterWhenReceived(lsdbAge.ageCounter());
        lspWrapper.setAgeCounterRollOverWhenAdded(lsdbAge.ageCounterRollOver());
        lspWrapper.setSelfOriginated(isSelfOriginated);
        lspWrapper.setIsisInterface(isisInterface);
        lspWrapper.setLsdbAge(lsdbAge);
        addLsp(lspWrapper, lspdu.lspId());

        log.debug("Added LSp In LSDB: {}", lspWrapper);

        return true;
    }

    /**
     * Adds the LSP to L1 or L2 database.
     *
     * @param lspWrapper LSA wrapper instance
     * @param key        key
     * @return True if added else false
     */
    private boolean addLsp(LspWrapper lspWrapper, String key) {
        //Remove the lsa from bin if exist.
        removeLspFromBin(lspWrapper);

        switch (lspWrapper.lsPdu().isisPduType()) {
            case L1LSPDU:
                isisL1Db.put(key, lspWrapper);
                break;
            case L2LSPDU:
                isisL2Db.put(key, lspWrapper);
                break;
            default:
                log.debug("Unknown LSP type to add..!!!");
                break;
        }

        //add it to bin
        Integer binNumber = lsdbAge.age2Bin(IsisConstants.LSPMAXAGE - lspWrapper.remainingLifetime());
        IsisLspBin lspBin = lsdbAge.getLspBin(binNumber);
        if (lspBin != null) {
            //remove from existing
            lspWrapper.setBinNumber(binNumber);
            lspBin.addIsisLsp(key, lspWrapper);
            lsdbAge.addLspBin(binNumber, lspBin);
            log.debug("Added Type {} LSP to LSDB and LSABin[{}], Remaining life time of LSA {}",
                      lspWrapper.lsPdu().isisPduType(),
                      binNumber, lspWrapper.remainingLifetime());
        }

        return false;
    }

    /**
     * Removes LSP from Bin.
     *
     * @param lsaWrapper LSP wrapper instance
     */
    public void removeLspFromBin(LspWrapper lsaWrapper) {
        if (lsaWrapper != null) {
            lsdbAge.removeLspFromBin(lsaWrapper);
        }
    }

    /**
     * Returns new ,latest or old according to the type of ISIS message received.
     *
     * @param lsp1 LSP instance
     * @param lsp2 LSP instance
     * @return string status
     */
    public String isNewerOrSameLsp(IsisMessage lsp1, IsisMessage lsp2) {
        LsPdu receivedLsp = (LsPdu) lsp1;
        LsPdu lspFromDb = (LsPdu) lsp2;
        if (receivedLsp.sequenceNumber() > lspFromDb.sequenceNumber()) {
            return "latest";
        } else if (receivedLsp.sequenceNumber() < lspFromDb.sequenceNumber()) {
            return "old";
        } else if (receivedLsp.sequenceNumber() == lspFromDb.sequenceNumber()) {
            return "same";
        }

        return "";
    }

    /**
     * Returns the sequence number.
     *
     * @param lspType type of LSP
     * @return sequence number
     */
    public int lsSequenceNumber(IsisPduType lspType) {
        switch (lspType) {
            case L1LSPDU:
                return l1LspSeqNo++;
            case L2LSPDU:
                return l2LspSeqNo++;
            default:
                return IsisConstants.STARTLSSEQUENCENUM;
        }
    }

    /**
     * Deletes the given LSP.
     *
     * @param lspMessage LSP instance
     */
    public void deleteLsp(IsisMessage lspMessage) {
        LsPdu lsp = (LsPdu) lspMessage;
        String lspKey = lsp.lspId();
        switch (lsp.isisPduType()) {
            case L1LSPDU:
                isisL1Db.remove(lspKey);
                break;
            case L2LSPDU:
                isisL2Db.remove(lspKey);
                break;
            default:
                log.debug("Unknown LSP type to remove..!!!");
                break;
        }
    }
}