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

import org.onlab.packet.Ip4Address;
import org.onlab.util.Bandwidth;
import org.onosproject.isis.controller.IsisNetworkType;
import org.onosproject.isis.controller.LspWrapper;
import org.onosproject.isis.controller.impl.topology.DefaultIsisLink;
import org.onosproject.isis.controller.impl.topology.DefaultIsisLinkInformation;
import org.onosproject.isis.controller.impl.topology.DefaultIsisLinkTed;
import org.onosproject.isis.controller.impl.topology.DefaultIsisRouter;
import org.onosproject.isis.controller.impl.topology.TopologyForDeviceAndLinkImpl;
import org.onosproject.isis.controller.topology.IsisLink;
import org.onosproject.isis.controller.topology.IsisLinkTed;
import org.onosproject.isis.controller.topology.IsisRouter;
import org.onosproject.isis.controller.topology.LinkInformation;
import org.onosproject.isis.io.isispacket.pdu.LsPdu;
import org.onosproject.isis.io.isispacket.tlv.IsExtendedReachability;
import org.onosproject.isis.io.isispacket.tlv.IsisTlv;
import org.onosproject.isis.io.isispacket.tlv.NeighborForExtendedIs;
import org.onosproject.isis.io.isispacket.tlv.subtlv.AdministrativeGroup;
import org.onosproject.isis.io.isispacket.tlv.subtlv.InterfaceIpAddress;
import org.onosproject.isis.io.isispacket.tlv.subtlv.MaximumBandwidth;
import org.onosproject.isis.io.isispacket.tlv.subtlv.MaximumReservableBandwidth;
import org.onosproject.isis.io.isispacket.tlv.subtlv.NeighborIpAddress;
import org.onosproject.isis.io.isispacket.tlv.subtlv.TrafficEngineeringMetric;
import org.onosproject.isis.io.isispacket.tlv.subtlv.TrafficEngineeringSubTlv;
import org.onosproject.isis.io.isispacket.tlv.subtlv.UnreservedBandwidth;
import org.onosproject.isis.io.util.IsisConstants;
import org.onosproject.isis.io.util.IsisUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;

/**
 * Representation of LSP event consumer.
 */
public class LspEventConsumer implements Runnable {
    private static final Logger log = LoggerFactory.getLogger(LspEventConsumer.class);
    private BlockingQueue queue = null;
    private Controller controller = null;
    private TopologyForDeviceAndLinkImpl deviceAndLink = new TopologyForDeviceAndLinkImpl();
    private Map<String, IsisRouter> isisRouterDetails = new LinkedHashMap<>();

    /**
     * Creates an instance of this.
     *
     * @param queue      blocking queue instance
     * @param controller controller instance
     */
    public LspEventConsumer(BlockingQueue queue, Controller controller) {
        this.queue = queue;
        this.controller = controller;
    }

    @Override
    public void run() {
        try {
            while (true) {
                if (!queue.isEmpty()) {
                    LspWrapper wrapper = (LspWrapper) queue.take();
                    LsPdu lsPdu = (LsPdu) wrapper.lsPdu();
                    if (wrapper.lspProcessing().equals(IsisConstants.LSPREMOVED)) {
                        callTopologyToRemoveInfo(lsPdu);
                    } else if (wrapper.lspProcessing().equals(IsisConstants.LSPADDED)) {
                        callTopologyToSendInfo(lsPdu, wrapper.isisInterface().networkType(),
                                               wrapper.isisInterface().systemId() + ".00");
                    }
                }
            }
        } catch (Exception e) {
            log.debug("Error::LspsForProvider::{}", e.getMessage());
        }
    }

    /**
     * Sends topology information to core.
     *
     * @param lsPdu           ls pdu instance
     * @param isisNetworkType ISIS network type
     * @param ownSystemId own system ID
     */
    private void callTopologyToSendInfo(LsPdu lsPdu, IsisNetworkType isisNetworkType,
                                        String ownSystemId) {
        if ((lsPdu.lspId().equals(ownSystemId + "-00"))) {
            return;
        }
        sendDeviceInfo(createDeviceInfo(lsPdu));

        for (IsisTlv isisTlv : lsPdu.tlvs()) {
            if (isisTlv instanceof IsExtendedReachability) {
                IsExtendedReachability isExtendedReachability = (IsExtendedReachability) isisTlv;
                List<NeighborForExtendedIs> neighbours = isExtendedReachability.neighbours();
                for (NeighborForExtendedIs teTlv : neighbours) {
                    String neighbor = teTlv.neighborId();
                    IsisRouter isisRouter = isisRouterDetails.get(neighbor);
                    if (isisRouter != null) {
                        IsisRouter sourceRouter = isisRouterDetails.get(IsisUtil.removeTailingZeros(lsPdu.lspId()));
                        IsisRouter destinationRouter = isisRouter;
                        if (sourceRouter.isDis()) {
                            LinkInformation linkInformation = createLinkInfo(sourceRouter.systemId(),
                                                                             destinationRouter.systemId(),
                                                                             sourceRouter.interfaceId(),
                                                                             destinationRouter.interfaceId(), lsPdu);
                            controller.addLinkDetails(createIsisLink(linkInformation, lsPdu));
                        } else if (destinationRouter.isDis()) {
                            LinkInformation linkInformation1 = createLinkInfo(destinationRouter.systemId(),
                                                                              sourceRouter.systemId(),
                                                                              destinationRouter.interfaceId(),
                                                                              sourceRouter.interfaceId(), lsPdu);
                            controller.addLinkDetails(createIsisLink(linkInformation1, lsPdu));
                        } else {
                            LinkInformation linkInformation = createLinkInfo(sourceRouter.systemId(),
                                                                             destinationRouter.systemId(),
                                                                             sourceRouter.interfaceId(),
                                                                             destinationRouter.interfaceId(), lsPdu);
                            controller.addLinkDetails(createIsisLink(linkInformation, lsPdu));
                            LinkInformation linkInformation1 = createLinkInfo(destinationRouter.systemId(),
                                                                              sourceRouter.systemId(),
                                                                              destinationRouter.interfaceId(),
                                                                              sourceRouter.interfaceId(), lsPdu);
                            controller.addLinkDetails(createIsisLink(linkInformation1, lsPdu));
                        }
                    }
                }
            }
        }
    }

    /**
     * Removes topology information from core.
     *
     * @param lsPdu ls pdu instance
     */
    private void callTopologyToRemoveInfo(LsPdu lsPdu) {
        String routerId = IsisUtil.removeTailingZeros(lsPdu.lspId());
        IsisRouter isisRouter = isisRouterDetails.get(routerId);
        removeDeviceInfo(isisRouter);
        removeLinkInfo(lsPdu);
    }

    /**
     * Sends the device information to topology provider.
     *
     * @param isisRouter ISIS router instance
     */
    private void sendDeviceInfo(IsisRouter isisRouter) {
        if (isisRouter.systemId() != null) {
            controller.addDeviceDetails(isisRouter);
        }
    }

    /**
     * Creates Device instance.
     *
     * @param lsPdu ISIS LSPDU instance
     * @return isisRouter isisRouter instance
     */
    public IsisRouter createDeviceInfo(LsPdu lsPdu) {
        IsisRouter isisRouter = createIsisRouter(lsPdu);
        if (isisRouter.systemId() != null) {
            isisRouterDetails.put(isisRouter.systemId(), isisRouter);
        }
        return isisRouter;
    }

    /**
     * Creates ISIS router instance.
     *
     * @param lsPdu lsp instance
     * @return isisRouter instance
     */
    private IsisRouter createIsisRouter(LsPdu lsPdu) {
        IsisRouter isisRouter = new DefaultIsisRouter();
        if (IsisUtil.checkIsDis(lsPdu.lspId())) {
            isisRouter.setDis(true);
        } else {
            isisRouter.setDis(false);
        }
        isisRouter.setSystemId(IsisUtil.removeTailingZeros(lsPdu.lspId()));
        for (IsisTlv isisTlv : lsPdu.tlvs()) {
            if (isisTlv instanceof IsExtendedReachability) {
                IsExtendedReachability isExtendedReachability = (IsExtendedReachability) isisTlv;
                List<NeighborForExtendedIs> neighbours = isExtendedReachability.neighbours();
                for (NeighborForExtendedIs teTlv : neighbours) {
                    List<TrafficEngineeringSubTlv> teSubTlvs = teTlv.teSubTlv();
                    for (TrafficEngineeringSubTlv teSubTlv : teSubTlvs) {
                        if (teSubTlv instanceof InterfaceIpAddress) {
                            InterfaceIpAddress localIpAddress = (InterfaceIpAddress) teSubTlv;
                            isisRouter.setInterfaceId(localIpAddress.localInterfaceIPAddress());
                        } else if (teSubTlv instanceof NeighborIpAddress) {
                            NeighborIpAddress neighborIpAddress = (NeighborIpAddress) teSubTlv;
                            isisRouter.setNeighborRouterId(neighborIpAddress.neighborIPAddress());
                        }

                    }
                }
            }
        }
        if (isisRouter.interfaceId() == null) {
            isisRouter.setInterfaceId(IsisConstants.DEFAULTIP);
        }
        if (isisRouter.neighborRouterId() == null) {
            isisRouter.setNeighborRouterId(IsisConstants.DEFAULTIP);
        }
        return isisRouter;
    }

    /**
     * Creates link information.
     *
     * @param localSystemId  local system ID
     * @param remoteSystemId remote system ID
     * @return link information
     * @param interfaceIp interface address
     * @param neighborIp neighbor address
     * @param lsPdu link state PDU instance
     * @return link information instance
     */
    public LinkInformation createLinkInfo(String localSystemId, String remoteSystemId,
                                          Ip4Address interfaceIp, Ip4Address neighborIp,
                                          LsPdu lsPdu) {

        String linkId = "link:" + localSystemId + "-" + remoteSystemId;
        LinkInformation linkInformation = new DefaultIsisLinkInformation();
        linkInformation.setInterfaceIp(interfaceIp);
        linkInformation.setNeighborIp(neighborIp);
        linkInformation.setLinkId(linkId);
        linkInformation.setAlreadyCreated(false);
        linkInformation.setLinkDestinationId(remoteSystemId);
        linkInformation.setLinkSourceId(localSystemId);

        return linkInformation;
    }

    /**
     * Removes the device information from topology provider.
     *
     * @param isisRouter ISIS router instance
     */
    private void removeDeviceInfo(IsisRouter isisRouter) {
        if (isisRouter.systemId() != null) {
            controller.removeDeviceDetails(isisRouter);
        }
        isisRouterDetails.remove(isisRouter.systemId());
    }


    /**
     * Removes the link information from topology provider.
     *
     * @param lsPdu ls pdu instance
     */
    private void removeLinkInfo(LsPdu lsPdu) {
        Map<String, LinkInformation> linkInformationList = deviceAndLink.removeLinkInfo(lsPdu.lspId());
        for (String key : linkInformationList.keySet()) {
            LinkInformation linkInformation = linkInformationList.get(key);
            controller.removeLinkDetails(createIsisLink(linkInformation, lsPdu));
        }
    }

    /**
     * Creates ISIS link instance.
     *
     * @param linkInformation link information instance
     * @return isisLink instance
     */
    private IsisLink createIsisLink(LinkInformation linkInformation, LsPdu lsPdu) {
        IsisLink isisLink = new DefaultIsisLink();
        isisLink.setLocalSystemId(linkInformation.linkSourceId());
        isisLink.setRemoteSystemId(linkInformation.linkDestinationId());
        isisLink.setInterfaceIp(linkInformation.interfaceIp());
        isisLink.setNeighborIp(linkInformation.neighborIp());
        isisLink.setLinkTed(createIsisLinkTedInfo(lsPdu));
        return isisLink;
    }

    /**
     * Creates the ISIS link TED information.
     *
     * @param lsPdu link state PDU
     * @return isisLinkTed
     */
    public IsisLinkTed createIsisLinkTedInfo(LsPdu lsPdu) {
        IsisLinkTed isisLinkTed = new DefaultIsisLinkTed();
        for (IsisTlv isisTlv : lsPdu.tlvs()) {
            if (isisTlv instanceof IsExtendedReachability) {
                IsExtendedReachability isExtendedReachability = (IsExtendedReachability) isisTlv;
                List<NeighborForExtendedIs> neighbours = isExtendedReachability.neighbours();
                for (NeighborForExtendedIs teTlv : neighbours) {
                    List<TrafficEngineeringSubTlv> teSubTlvs = teTlv.teSubTlv();
                    for (TrafficEngineeringSubTlv teSubTlv : teSubTlvs) {
                        if (teSubTlv instanceof AdministrativeGroup) {
                            AdministrativeGroup ag = (AdministrativeGroup) teSubTlv;
                            isisLinkTed.setAdministrativeGroup(ag.administrativeGroup());
                        }
                        if (teSubTlv instanceof InterfaceIpAddress) {
                            InterfaceIpAddress localIpAddress = (InterfaceIpAddress) teSubTlv;
                            isisLinkTed.setIpv4InterfaceAddress(localIpAddress.localInterfaceIPAddress());
                        }
                        if (teSubTlv instanceof NeighborIpAddress) {
                            NeighborIpAddress neighborIpAddress = (NeighborIpAddress) teSubTlv;
                            isisLinkTed.setIpv4NeighborAddress(neighborIpAddress.neighborIPAddress());
                        }
                        if (teSubTlv instanceof TrafficEngineeringMetric) {
                            TrafficEngineeringMetric teM = (TrafficEngineeringMetric) teSubTlv;
                            isisLinkTed.setTeDefaultMetric(teM.getTrafficEngineeringMetricValue());
                        }
                        if (teSubTlv instanceof MaximumBandwidth) {
                            MaximumBandwidth maxLinkBandwidth = (MaximumBandwidth) teSubTlv;
                            isisLinkTed.setMaximumLinkBandwidth(
                                    Bandwidth.bps(maxLinkBandwidth.getMaximumBandwidthValue()));
                        }
                        if (teSubTlv instanceof MaximumReservableBandwidth) {
                            MaximumReservableBandwidth maxReservableBw = (MaximumReservableBandwidth) teSubTlv;
                            isisLinkTed.setMaximumReservableLinkBandwidth(
                                    Bandwidth.bps(maxReservableBw.getMaximumBandwidthValue()));
                        }
                        if (teSubTlv instanceof UnreservedBandwidth) {
                            UnreservedBandwidth unReservedBandwidth = (UnreservedBandwidth) teSubTlv;
                            List<Bandwidth> bandwidthList = new ArrayList<>();
                            List<Float> unReservedBandwidthList = unReservedBandwidth.unReservedBandwidthValue();
                            for (Float unReservedBandwidthFloatValue : unReservedBandwidthList) {
                                Bandwidth bandwidth = Bandwidth.bps(unReservedBandwidthFloatValue);
                                bandwidthList.add(bandwidth);
                            }
                            isisLinkTed.setUnreservedBandwidth(bandwidthList);
                        }
                    }
                }
            }
        }
        return isisLinkTed;
    }
}