/**
 * 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.tetopology.management;

import static org.onosproject.tetopology.management.api.OptimizationType.NOT_OPTIMIZED;
import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_ADDED;
import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.NETWORK_REMOVED;
import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_ADDED;
import static org.onosproject.tetopology.management.api.TeTopologyEvent.Type.TE_TOPOLOGY_REMOVED;
import static org.slf4j.LoggerFactory.getLogger;

import java.util.BitSet;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Service;
import org.onosproject.net.DeviceId;
import org.onosproject.store.AbstractStore;
import org.onosproject.tetopology.management.api.CommonTopologyData;
import org.onosproject.tetopology.management.api.DefaultNetwork;
import org.onosproject.tetopology.management.api.DefaultTeTopologies;
import org.onosproject.tetopology.management.api.DefaultTeTopology;
import org.onosproject.tetopology.management.api.KeyId;
import org.onosproject.tetopology.management.api.Network;
import org.onosproject.tetopology.management.api.OptimizationType;
import org.onosproject.tetopology.management.api.TeConstants;
import org.onosproject.tetopology.management.api.TeTopologies;
import org.onosproject.tetopology.management.api.TeTopology;
import org.onosproject.tetopology.management.api.TeTopologyEvent;
import org.onosproject.tetopology.management.api.TeTopologyId;
import org.onosproject.tetopology.management.api.TeTopologyKey;
import org.onosproject.tetopology.management.api.TeUtils;
import org.onosproject.tetopology.management.api.link.DefaultNetworkLink;
import org.onosproject.tetopology.management.api.link.DefaultTeLink;
import org.onosproject.tetopology.management.api.link.NetworkLink;
import org.onosproject.tetopology.management.api.link.NetworkLinkKey;
import org.onosproject.tetopology.management.api.link.TeLink;
import org.onosproject.tetopology.management.api.link.TeLinkTpGlobalKey;
import org.onosproject.tetopology.management.api.link.TeLinkTpKey;
import org.onosproject.tetopology.management.api.node.ConnectivityMatrix;
import org.onosproject.tetopology.management.api.node.ConnectivityMatrixKey;
import org.onosproject.tetopology.management.api.node.DefaultNetworkNode;
import org.onosproject.tetopology.management.api.node.DefaultTeNode;
import org.onosproject.tetopology.management.api.node.DefaultTerminationPoint;
import org.onosproject.tetopology.management.api.node.NetworkNode;
import org.onosproject.tetopology.management.api.node.NetworkNodeKey;
import org.onosproject.tetopology.management.api.node.NodeTpKey;
import org.onosproject.tetopology.management.api.node.TeNode;
import org.onosproject.tetopology.management.api.node.TeNodeKey;
import org.onosproject.tetopology.management.api.node.TerminationPoint;
import org.onosproject.tetopology.management.api.node.TerminationPointKey;
import org.onosproject.tetopology.management.api.node.TtpKey;
import org.onosproject.tetopology.management.api.node.TunnelTerminationPoint;
import org.onosproject.tetopology.management.impl.InternalNetwork;
import org.onosproject.tetopology.management.impl.InternalNetworkLink;
import org.onosproject.tetopology.management.impl.InternalNetworkNode;
import org.onosproject.tetopology.management.impl.InternalTeLink;
import org.onosproject.tetopology.management.impl.InternalTeNode;
import org.onosproject.tetopology.management.impl.InternalTeTopology;
import org.onosproject.tetopology.management.impl.InternalTerminationPoint;
import org.onosproject.tetopology.management.impl.TeMgrUtil;
import org.onosproject.tetopology.management.impl.TeTopologyMapEvent;
import org.onosproject.tetopology.management.impl.TeTopologyStore;
import org.onosproject.tetopology.management.impl.TeTopologyStoreDelegate;
import org.slf4j.Logger;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

/**
 * Implementation of the TE network store.
 */
@Component(immediate = true)
@Service
public class SimpleTeTopologyStore
        extends AbstractStore<TeTopologyEvent, TeTopologyStoreDelegate>
        implements TeTopologyStore {
    private static final String STORE_NAME = "TE_NETWORK_TOPOLOGY_STORE";
    private final Logger log = getLogger(getClass());

    // Track TE topologies by TE Topology key
    private Map<TeTopologyKey, InternalTeTopology> teTopologyMap = Maps
            .newConcurrentMap();
    // Track networks by network Id
    private Map<KeyId, InternalNetwork> networkMap = Maps.newConcurrentMap();
    // Track TE nodes by TE node key
    private Map<TeNodeKey, InternalTeNode> teNodeMap = Maps.newConcurrentMap();
    // Track ConnectivityMatrix by its key
    private Map<ConnectivityMatrixKey, ConnectivityMatrix> connMatrixMap = Maps
            .newConcurrentMap();
    // Track Tunnel Termination Points by its key
    private Map<TtpKey, TunnelTerminationPoint> ttpMap = Maps
            .newConcurrentMap();
    // Track network nodes by network node key
    private Map<NetworkNodeKey, InternalNetworkNode> networkNodeMap = Maps
            .newConcurrentMap();
    // Track TE links by its key
    private Map<TeLinkTpGlobalKey, InternalTeLink> teLinkMap = Maps
            .newConcurrentMap();
    // Track network links by network link key
    private Map<NetworkLinkKey, InternalNetworkLink> networkLinkMap = Maps
            .newConcurrentMap();
    // Track Termination points by termination point key
    private Map<TerminationPointKey, InternalTerminationPoint> tpMap = Maps
            .newConcurrentMap();
    // Track termination point keys by TE termination point Key
    private Map<TeLinkTpGlobalKey, TerminationPointKey> tpKeyMap = Maps
            .newConcurrentMap();
    private long providerId;

    @Activate
    public void activate() {
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        teTopologyMap.clear();
        networkMap.clear();
        teNodeMap.clear();
        connMatrixMap.clear();
        networkNodeMap.clear();
        teLinkMap.clear();
        networkLinkMap.clear();
        tpMap.clear();
        tpKeyMap.clear();
        ttpMap.clear();
        log.info("Stopped");
    }

    @Override
    public TeTopologies teTopologies() {
        Map<TeTopologyKey, TeTopology> teTopologies = Maps.newHashMap();
        if (MapUtils.isNotEmpty(teTopologyMap)) {
            for (TeTopologyKey key : teTopologyMap.keySet()) {
                teTopologies.put(key, teTopology(key));
            }
        }
        return new DefaultTeTopologies(STORE_NAME, teTopologies);
    }

    private TeTopology teTopology(TeTopologyKey topologyId,
                                  InternalTeTopology intTopology) {
        if (intTopology == null) {
            return null;
        }
        Map<Long, TeNode> teNodes = null;
        if (CollectionUtils.isNotEmpty(intTopology.teNodeKeys())) {
            teNodes = Maps.newHashMap();
            for (TeNodeKey key : intTopology.teNodeKeys()) {
                teNodes.put(key.teNodeId(), teNode(key));
            }
        }
        Map<TeLinkTpKey, TeLink> teLinks = null;
        if (CollectionUtils.isNotEmpty(intTopology.teLinkKeys())) {
            teLinks = Maps.newHashMap();
            for (TeLinkTpGlobalKey key : intTopology.teLinkKeys()) {
                teLinks.put(key.teLinkTpKey(), teLink(key));
            }
        }
        return new DefaultTeTopology(topologyId, teNodes, teLinks,
                                     intTopology.teTopologyId(),
                                     intTopology.topologyData());
    }

    @Override
    public TeTopology teTopology(TeTopologyKey topologyId) {
        InternalTeTopology intTopology = teTopologyMap.get(topologyId);
        return teTopology(topologyId, intTopology);
    }

    private void removeTopologyeMapEntrys(InternalTeTopology curTopology) {
        // Remove TE nodes
        if (CollectionUtils.isNotEmpty(curTopology.teNodeKeys())) {
            for (TeNodeKey key : curTopology.teNodeKeys()) {
                removeTeNode(key, true);
            }
        }
        // Remove TE Links
        if (CollectionUtils.isNotEmpty(curTopology.teLinkKeys())) {
            for (TeLinkTpGlobalKey key : curTopology.teLinkKeys()) {
                removeTeLink(key, true);
            }
        }
    }

    @Override
    public void updateTeTopology(TeTopology teTopology) {
        InternalTeTopology curTopology = teTopologyMap
                .get(teTopology.teTopologyId());
        if (curTopology != null) {
            // Existing topology update
            // Remove existing map entries first, which should be removed by
            // its own events
            removeTopologyeMapEntrys(curTopology);
        }
        // Update TE nodes
        List<NetworkNodeKey> nodeIds = null;
        if (MapUtils.isNotEmpty(teTopology.teNodes())) {
            nodeIds = Lists.newArrayList();
            for (Map.Entry<Long, TeNode> entry : teTopology.teNodes()
                    .entrySet()) {
                TeNodeKey teNodeKey = new TeNodeKey(teTopology.teTopologyId(),
                                                    entry.getKey());
                NetworkNodeKey nodeKey = TeMgrUtil.networkNodeKey(teNodeKey);
                updateTeNode(teNodeKey, entry.getValue(), true, true, nodeKey);
                nodeIds.add(nodeKey);
            }
        }
        // Update TE links
        List<NetworkLinkKey> linkIds = null;
        if (MapUtils.isNotEmpty(teTopology.teLinks())) {
            linkIds = Lists.newArrayList();
            for (Map.Entry<TeLinkTpKey, TeLink> entry : teTopology.teLinks()
                    .entrySet()) {
                TeLinkTpGlobalKey teLinkKey = new TeLinkTpGlobalKey(teTopology
                        .teTopologyId(), entry.getKey());
                NetworkLinkKey linkKey = TeMgrUtil.networkLinkKey(teLinkKey);
                updateTeLink(teLinkKey, entry.getValue(), true, true, linkKey);
                linkIds.add(linkKey);
            }
        }
        // Finally Update teTopologyMap
        InternalTeTopology newTopology = new InternalTeTopology(teTopology);
        teTopologyMap.put(teTopology.teTopologyId(), newTopology);

        if (curTopology == null) {
            // New topology, update networkMap
            InternalNetwork intNetwork = new InternalNetwork();
            intNetwork.setServerProvided(false);
            intNetwork.setTeTopologyKey(teTopology.teTopologyId());
            intNetwork.setNodeIds(nodeIds);
            intNetwork.setLinkIds(linkIds);
            networkMap.put(teTopology.networkId(), intNetwork);
        }
    }

    @Override
    public void removeTeTopology(TeTopologyKey topologyId) {
        // Remove it from teTopologyMap
        InternalTeTopology topology = teTopologyMap.remove(topologyId);
        if (topology != null) {
            removeTopologyeMapEntrys(topology);
            // Remove it from networkMap;
            networkMap.remove(topology.topologyData().networkId());
        }
    }

    @Override
    public List<Network> networks() {
        if (MapUtils.isEmpty(networkMap)) {
            return null;
        }
        List<Network> networks = Lists.newArrayList();
        for (KeyId networkId : networkMap.keySet()) {
            networks.add(network(networkId));
        }
        return networks;
    }

    private Network network(KeyId networkId, InternalNetwork curNetwork) {
        if (curNetwork == null) {
            return null;
        }
        List<KeyId> supportingNetworkIds = curNetwork.supportingNetworkIds();
        Map<KeyId, NetworkNode> nodes = null;
        if (CollectionUtils.isNotEmpty(curNetwork.nodeIds())) {
            nodes = Maps.newHashMap();
            for (NetworkNodeKey key : curNetwork.nodeIds()) {
                nodes.put(key.nodeId(), networkNode(key));
            }
        }
        Map<KeyId, NetworkLink> links = null;
        if (CollectionUtils.isNotEmpty(curNetwork.linkIds())) {
            links = Maps.newHashMap();
            for (NetworkLinkKey key : curNetwork.linkIds()) {
                links.put(key.linkId(), networkLink(key));
            }
        }
        TeTopologyId topologyId = null;
        DeviceId ownerId = null;
        OptimizationType opt = NOT_OPTIMIZED;
        if (curNetwork.teTopologyKey() != null
                && teTopology(curNetwork.teTopologyKey()) != null) {
            topologyId = new TeTopologyId(curNetwork.teTopologyKey()
                    .providerId(), curNetwork.teTopologyKey().clientId(),
                                          teTopology(curNetwork.teTopologyKey())
                                                  .teTopologyIdStringValue());
            ownerId = teTopology(curNetwork.teTopologyKey()).ownerId();
            opt = teTopologyMap.get(curNetwork.teTopologyKey()).topologyData()
                    .optimization();
        }
        return new DefaultNetwork(networkId, supportingNetworkIds, nodes, links,
                                  topologyId, curNetwork.serverProvided(),
                                  ownerId, opt);
    }

    @Override
    public Network network(KeyId networkId) {
        InternalNetwork curNetwork = networkMap.get(networkId);
        return network(networkId, curNetwork);
    }

    private void removeNetworkMapEntrys(InternalNetwork curNetwork,
                                        boolean teRemove) {
        // Remove TE nodes
        if (CollectionUtils.isNotEmpty(curNetwork.nodeIds())) {
            for (NetworkNodeKey key : curNetwork.nodeIds()) {
                removeNetworkNode(key, teRemove);
            }
        }
        // Remove TE Links
        if (CollectionUtils.isNotEmpty(curNetwork.linkIds())) {
            for (NetworkLinkKey key : curNetwork.linkIds()) {
                removeNetworkLink(key, teRemove);
            }
        }
    }

    private TeTopologyKey newTeTopologyKey(TeTopologyId teTopologyId) {
        long idValue;
        try {
            idValue = Long.parseLong(teTopologyId.topologyId());
        } catch (NumberFormatException e) {
            // Can't get the long value from the string.
            // Use an assigned id value from local id pool,
            // Ideally id should be assigned per provider base.
            idValue = nextTeTopologyId();
        }
        return new TeTopologyKey(teTopologyId.providerId(),
                                 teTopologyId.clientId(), idValue);
    }

    @Override
    public void updateNetwork(Network network) {
        InternalNetwork curNetwork = networkMap.get(network.networkId());
        if (curNetwork != null) {
            // Existing topology update
            // Remove existing map entries first,
            removeNetworkMapEntrys(curNetwork, false);
        }
        TeTopologyKey topoKey = null;
        if (network.teTopologyId() != null) {
            topoKey = newTeTopologyKey(network.teTopologyId());
        }
        // Update TE nodes
        List<TeNodeKey> teNodeKeys = null;
        if (MapUtils.isNotEmpty(network.nodes())) {
            teNodeKeys = Lists.newArrayList();
            for (Map.Entry<KeyId, NetworkNode> entry : network.nodes()
                    .entrySet()) {
                NetworkNodeKey nodeKey = new NetworkNodeKey(network.networkId(),
                                                            entry.getKey());
                TeNodeKey teNodeKey = null;
                if (topoKey != null && entry.getValue().teNode() != null) {
                    teNodeKey = new TeNodeKey(topoKey, entry.getValue().teNode()
                            .teNodeId());
                }
                updateNetworkNode(nodeKey, entry.getValue(), true, false,
                                  teNodeKey);
                teNodeKeys.add(teNodeKey);
            }
        }
        // Update TE links
        List<TeLinkTpGlobalKey> teLinkKeys = null;
        if (MapUtils.isNotEmpty(network.links())) {
            teLinkKeys = Lists.newArrayList();
            for (Map.Entry<KeyId, NetworkLink> entry : network.links()
                    .entrySet()) {
                NetworkLinkKey linkKey = new NetworkLinkKey(network.networkId(),
                                                            entry.getKey());
                TeLinkTpGlobalKey teLinkKey = null;
                if (topoKey != null && entry.getValue().teLink() != null) {
                    teLinkKey = new TeLinkTpGlobalKey(topoKey, entry.getValue()
                            .teLink().teLinkKey());
                }
                updateNetworkLink(linkKey, entry.getValue(), true, false,
                                  teLinkKey);
                teLinkKeys.add(teLinkKey);
            }
        }

        // New network, update TE Topology first
        if (curNetwork == null) {
            InternalTeTopology intTopo = new InternalTeTopology(network
                    .teTopologyId().topologyId());
            intTopo.setTeNodeKeys(teNodeKeys);
            intTopo.setTeLinkKeys(teLinkKeys);
            BitSet flags = new BitSet(TeConstants.FLAG_MAX_BITS);
            flags.set(TeTopology.BIT_LEARNT);
            if (network.teTopologyId().clientId() == providerId) {
                // Hard rule for now
                flags.set(TeTopology.BIT_CUSTOMIZED);
            }
            CommonTopologyData common = new CommonTopologyData(network.networkId(), NOT_OPTIMIZED,
                                                               flags, network.ownerId());
            intTopo.setTopologydata(common);
            teTopologyMap.put(topoKey, intTopo);
            // Assume new topology
            TeTopologyEvent topologyEvent = new TeTopologyEvent(TE_TOPOLOGY_ADDED,
                                                                teTopology(topoKey));
            notifyDelegate(topologyEvent);
        }
        // Finally Update networkMap
        InternalNetwork newNetwork = new InternalNetwork(network);
        newNetwork.setTeTopologyKey(topoKey);
        networkMap.put(network.networkId(), newNetwork);
        // Assume new network
        TeTopologyEvent topologyEvent = new TeTopologyEvent(NETWORK_ADDED,
                                                            network(network.networkId()));
        notifyDelegate(topologyEvent);
    }

    @Override
    public void removeNetwork(KeyId networkId) {
        // Remove it from networkMap
        InternalNetwork network = networkMap.remove(networkId);
        TeTopologyEvent topologyEvent = new TeTopologyEvent(NETWORK_REMOVED,
                                                            new DefaultNetwork(networkId,
                                                                               null,
                                                                               null,
                                                                               null,
                                                                               null,
                                                                               false,
                                                                               null,
                                                                               NOT_OPTIMIZED));
        notifyDelegate(topologyEvent);
        if (network != null && network.teTopologyKey() != null) {
            removeNetworkMapEntrys(network, false);
            teTopologyMap.remove(network.teTopologyKey());
            topologyEvent = new TeTopologyEvent(TE_TOPOLOGY_REMOVED,
                                                new DefaultTeTopology(network
                                                        .teTopologyKey(), null, null, null, null));
            notifyDelegate(topologyEvent);
        }
    }

    private TeNode teNode(TeNodeKey nodeKey, InternalTeNode intNode) {
        if (intNode == null) {
            return null;
        }
        Map<Long, ConnectivityMatrix> connMatrices = null;
        if (CollectionUtils.isNotEmpty(intNode.connMatrixKeys())) {
            connMatrices = Maps.newHashMap();
            for (ConnectivityMatrixKey key : intNode.connMatrixKeys()) {
                connMatrices.put(key.entryId(), connMatrixMap.get(key));
            }
        }
        List<Long> teLinkIds = null;
        if (CollectionUtils.isNotEmpty(intNode.teLinkTpKeys())) {
            teLinkIds = Lists.newArrayList();
            for (TeLinkTpGlobalKey key : intNode.teLinkTpKeys()) {
                teLinkIds = TeUtils.addListElement(teLinkIds, key.teLinkTpId());
            }
        }
        List<Long> tps = null;
        if (CollectionUtils.isNotEmpty(intNode.teTpKeys())) {
            tps = Lists.newArrayList();
            for (TeLinkTpGlobalKey key : intNode.teTpKeys()) {
                tps = TeUtils.addListElement(tps, key.teLinkTpId());
            }
        }
        Map<Long, TunnelTerminationPoint> ttps = null;
        if (CollectionUtils.isNotEmpty(intNode.ttpKeys())) {
            ttps = Maps.newHashMap();
            for (TtpKey key : intNode.ttpKeys()) {
                ttps.put(key.ttpId(), ttpMap.get(key));
            }
        }
        return new DefaultTeNode(nodeKey.teNodeId(),
                                 intNode.underlayTopologyKey(),
                                 intNode.supportNodeKey(),
                                 intNode.sourceTeNodeKey(), intNode.teData(),
                                 connMatrices, teLinkIds, ttps, tps);
    }

    @Override
    public TeNode teNode(TeNodeKey nodeKey) {
        InternalTeNode intNode = teNodeMap.get(nodeKey);
        return teNode(nodeKey, intNode);
    }

    private void removeTeNodeMapEntrys(InternalTeNode intNode) {
        // Remove connMatrixMap entries for the node
        if (CollectionUtils.isNotEmpty(intNode.connMatrixKeys())) {
            for (ConnectivityMatrixKey key : intNode.connMatrixKeys()) {
                connMatrixMap.remove(key);
            }
        }
        // Remove ttpMap entries for the node
        if (CollectionUtils.isNotEmpty(intNode.ttpKeys())) {
            for (TtpKey key : intNode.ttpKeys()) {
                ttpMap.remove(key);
            }
        }
    }

    private void updateTeNode(TeNodeKey nodeKey, TeNode node,
                              boolean parentUpdate, boolean teNodeUpdate,
                              NetworkNodeKey networkNodeKey) {
        InternalTeTopology intTopo = teTopologyMap.get(nodeKey.teTopologyKey());
        if (intTopo == null && !parentUpdate) {
            log.error("TE Topology is not in dataStore for nodeUpdate {}",
                      nodeKey);
            return;
        }
        InternalTeNode curNode = teNodeMap.get(nodeKey);
        // Update connMatrixMap
        if (MapUtils.isNotEmpty(node.connectivityMatrices())) {
            for (Map.Entry<Long, ConnectivityMatrix> entry : node
                    .connectivityMatrices().entrySet()) {
                connMatrixMap
                        .put(new ConnectivityMatrixKey(nodeKey, entry.getKey()),
                             entry.getValue());
            }
        }
        // Update ttpMap
        if (MapUtils.isNotEmpty(node.tunnelTerminationPoints())) {
            for (Map.Entry<Long, TunnelTerminationPoint> entry : node
                    .tunnelTerminationPoints().entrySet()) {
                ttpMap.put(new TtpKey(nodeKey, entry.getKey()),
                           entry.getValue());
            }
        }
        // Update TE Termination Points

        // Update teNodeMap
        InternalTeNode intNode = new InternalTeNode(nodeKey, node,
                                                    networkNodeKey,
                                                    parentUpdate);
        teNodeMap.put(nodeKey, intNode);
        if (curNode == null && !parentUpdate && intTopo != null) {
            // Update InternalTeTopology
            intTopo.setChildUpdate(true);
            TeUtils.addListElement(intTopo.teNodeKeys(), nodeKey);
        }
        // Update networkNodeMap
        if (teNodeUpdate) {
            updateNetworkNode(networkNodeKey, networkNode(node), parentUpdate,
                              teNodeUpdate, nodeKey);
        }
    }

    private NetworkNode networkNode(TeNode node) {
        KeyId nodeId = KeyId.keyId(Long.toString(node.teNodeId()));
        List<NetworkNodeKey> supportingNodeIds = null;
        if (node.supportingTeNodeId() != null) {
            supportingNodeIds = Lists.newArrayList();
            supportingNodeIds.add(new NetworkNodeKey(TeMgrUtil.toNetworkId((node
                    .supportingTeNodeId().teTopologyKey())), KeyId.keyId(Long
                            .toString(node.supportingTeNodeId().teNodeId()))));
        }
        Map<KeyId, TerminationPoint> tps = null;
        if (node.teTerminationPointIds() != null) {
            tps = Maps.newHashMap();
            for (Long teTpId : node.teTerminationPointIds()) {
                tps.put(KeyId.keyId(Long.toString(teTpId)),
                        new DefaultTerminationPoint(KeyId
                                .keyId(Long.toString(teTpId)), null, teTpId));
            }
        }
        return new DefaultNetworkNode(nodeId, supportingNodeIds, node, tps);
    }

    @Override
    public void updateTeNode(TeNodeKey nodeKey, TeNode node) {
        updateTeNode(nodeKey, node, false, true,
                     TeMgrUtil.networkNodeKey(nodeKey));
    }

    private void removeTeNode(TeNodeKey nodeKey, boolean teNodeRemove) {
        // Remove it from InternalTeTopology first
        InternalTeTopology intTopo = teTopologyMap.get(nodeKey.teTopologyKey());
        if (intTopo != null
                && CollectionUtils.isNotEmpty(intTopo.teNodeKeys())) {
            intTopo.setChildUpdate(true);
            intTopo.teNodeKeys().remove(nodeKey);
        }
        // Then remove it from teNodeMap
        InternalTeNode node = teNodeMap.remove(nodeKey);
        removeTeNodeMapEntrys(node);
        // Remove it from networkNodeMap
        if (teNodeRemove && node != null) {
            removeNetworkNode(node.networkNodeKey(), teNodeRemove);
        }
    }

    @Override
    public void removeTeNode(TeNodeKey nodeKey) {
        removeTeNode(nodeKey, true);
    }

    private NetworkNode networkNode(NetworkNodeKey nodeKey,
                                    InternalNetworkNode intNode) {
        if (intNode == null) {
            return null;
        }
        Map<KeyId, TerminationPoint> tps = Maps.newHashMap();
        for (KeyId tpId : intNode.tpIds()) {
            tps.put(tpId,
                    terminationPoint(new TerminationPointKey(nodeKey, tpId)));

        }
        return new DefaultNetworkNode(nodeKey.nodeId(),
                                      intNode.supportingNodeIds(),
                                      teNode(intNode.teNodeKey()), tps);
    }

    @Override
    public NetworkNode networkNode(NetworkNodeKey nodeKey) {
        InternalNetworkNode intNode = networkNodeMap.get(nodeKey);
        return networkNode(nodeKey, intNode);
    }

    private void updateNetworkNode(NetworkNodeKey nodeKey, NetworkNode node,
                                   boolean parentUpdate, boolean teNodeUpdate,
                                   TeNodeKey teNodeKey) {
        InternalNetwork intNework = null;
        if (!parentUpdate) {
            intNework = networkMap.get(nodeKey.networkId());
            if (intNework == null) {
                log.error("Network is not in dataStore for nodeUpdate {}",
                          nodeKey);
                return;
            }
        }

        InternalNetworkNode exNode = networkNodeMap.get(nodeKey);
        if (exNode != null && CollectionUtils.isNotEmpty(exNode.tpIds())) {
            // Remove the TerminationPoints first
            for (KeyId tpId : exNode.tpIds()) {
                removeTerminationPoint(new TerminationPointKey(nodeKey, tpId));
            }
        }

        if (MapUtils.isNotEmpty(node.terminationPoints())) {
            // Update with new TerminationPoints
            for (Map.Entry<KeyId, TerminationPoint> entry : node
                    .terminationPoints().entrySet()) {
                updateTerminationPoint(new TerminationPointKey(nodeKey,
                                                               entry.getKey()),
                                       entry.getValue(), parentUpdate,
                                       teNodeKey);
            }
        }

        // Update teNodeMap first
        if (!teNodeUpdate && teNodeKey != null && node.teNode() != null) {
            updateTeNode(teNodeKey, node.teNode(), parentUpdate, teNodeUpdate,
                         nodeKey);
        }
        // Update networkNodeMap
        InternalNetworkNode intNode = new InternalNetworkNode(node,
                                                              parentUpdate);
        intNode.setTeNodeKey(teNodeKey);
        networkNodeMap.put(nodeKey, intNode);
        if (exNode == null && !parentUpdate && intNework != null) {
            // Update the InternalNetwork
            intNework.setChildUpdate(true);
            TeUtils.addListElement(intNework.nodeIds(), nodeKey);
        }
    }

    @Override
    public void updateNetworkNode(NetworkNodeKey nodeKey, NetworkNode node) {
        TeNodeKey teNodeKey = null;
        if (node.teNode() != null) {
            teNodeKey = new TeNodeKey(networkMap.get(nodeKey.networkId())
                    .teTopologyKey(), node.teNode().teNodeId());
        }
        updateNetworkNode(nodeKey, node, false, false, teNodeKey);
    }

    private void removeNetworkNode(NetworkNodeKey nodeKey,
                                   boolean teNodeRemove) {
        // Update the InternalNetwork
        InternalNetwork intNework = networkMap.get(nodeKey.networkId());
        if (intNework != null
                && CollectionUtils.isNotEmpty(intNework.nodeIds())) {
            intNework.setChildUpdate(true);
            intNework.nodeIds().remove(nodeKey.nodeId());
        }
        InternalNetworkNode intNode = networkNodeMap.remove(nodeKey);
        if (intNode != null && CollectionUtils.isNotEmpty(intNode.tpIds())) {
            // Remove the TerminationPoints first
            for (KeyId tpId : intNode.tpIds()) {
                removeTerminationPoint(new TerminationPointKey(nodeKey, tpId));
            }
        }
        if (!teNodeRemove && intNode != null) {
            // Now remove it from teNodeMap
            removeTeNode(intNode.teNodeKey(), teNodeRemove);
        }
    }

    @Override
    public void removeNetworkNode(NetworkNodeKey nodeKey) {
        removeNetworkNode(nodeKey, false);
    }

    private TeLink teLink(TeLinkTpGlobalKey linkKey, InternalTeLink intLink) {
        if (intLink == null) {
            return null;
        }
        return new DefaultTeLink(linkKey.teLinkTpKey(), intLink.peerTeLinkKey(),
                                 intLink.underlayTopologyKey(),
                                 intLink.supportingLinkKey(),
                                 intLink.sourceTeLinkKey(), intLink.teData());
    }

    @Override
    public TeLink teLink(TeLinkTpGlobalKey linkKey) {
        InternalTeLink intLink = teLinkMap.get(linkKey);
        return teLink(linkKey, intLink);
    }

    private void updateTeLink(TeLinkTpGlobalKey linkKey, TeLink link,
                              boolean parentUpdate, boolean teLinkUpdate,
                              NetworkLinkKey networkLinkKey) {
        InternalTeTopology intTopo = teTopologyMap.get(linkKey.teTopologyKey());
        if (intTopo == null && !parentUpdate) {
            log.error("TE Topology is not in dataStore for linkUpdate {}",
                      linkKey);
            return;
        }
        InternalTeNode intNode = teNodeMap.get(linkKey.teNodeKey());
        if (intNode == null && !parentUpdate) {
            log.error("TE node is not in dataStore for linkUpdate {}", linkKey);
            return;
        }
        InternalTeLink exLink = teLinkMap.get(linkKey);

        // Update teLinkMap
        InternalTeLink intLink = new InternalTeLink(link, parentUpdate);
        intLink.setNetworkLinkKey(networkLinkKey);
        teLinkMap.put(linkKey, intLink);
        if (exLink == null && !parentUpdate) {
            if (intTopo != null) {
                // Update the InternalTeTopology
                intTopo.setChildUpdate(true);
                intTopo.setTeLinkKeys(TeUtils
                        .addListElement(intTopo.teLinkKeys(), linkKey));
            }
            if (intNode != null) {
                // Update the InternalNode
                intNode.setChildUpdate(true);
                intNode.setTeLinkTpKeys(TeUtils
                        .addListElement(intNode.teLinkTpKeys(), linkKey));
            }
        }

        // Update networkLinkMap
        if (teLinkUpdate) {
            updateNetworkLink(networkLinkKey, networkLink(link), parentUpdate,
                              teLinkUpdate, linkKey);
        }
    }

    private NetworkLink networkLink(TeLink link) {
        KeyId linkId = TeMgrUtil.toNetworkLinkId(link.teLinkKey());
        NodeTpKey source = null;
        if (link.teLinkKey() != null) {
            source = new NodeTpKey(KeyId
                    .keyId(Long.toString(link.teLinkKey().teNodeId())), KeyId
                            .keyId(Long
                                    .toString(link.teLinkKey().teLinkTpId())));
        }
        NodeTpKey dest = null;
        if (link.peerTeLinkKey() != null) {
            dest = new NodeTpKey(KeyId
                    .keyId(Long.toString(link.peerTeLinkKey().teNodeId())),
                                 KeyId.keyId(Long.toString(link.peerTeLinkKey()
                                         .teLinkTpId())));
        }
        List<NetworkLinkKey> supportingLinkIds = null;
        if (link.supportingTeLinkId() != null) {
            supportingLinkIds = Lists.newArrayList();
            supportingLinkIds.add(new NetworkLinkKey(TeMgrUtil.toNetworkId(link
                    .supportingTeLinkId().teTopologyKey()), TeMgrUtil
                            .toNetworkLinkId(link.supportingTeLinkId()
                                    .teLinkTpKey())));
        }
        return new DefaultNetworkLink(linkId, source, dest, supportingLinkIds,
                                      link);
    }

    @Override
    public void updateTeLink(TeLinkTpGlobalKey linkKey, TeLink link) {
        updateTeLink(linkKey, link, false, true,
                     TeMgrUtil.networkLinkKey(linkKey));
    }

    private void removeTeLink(TeLinkTpGlobalKey linkKey, boolean teLinkRemove) {
        // Remove it from InternalTeTopology first
        InternalTeTopology intTopo = teTopologyMap.get(linkKey.teTopologyKey());
        if (intTopo != null
                && CollectionUtils.isNotEmpty(intTopo.teLinkKeys())) {
            intTopo.setChildUpdate(true);
            intTopo.teLinkKeys().remove(linkKey);
        }
        // Remove it from InternalTeNode
        InternalTeNode intNode = teNodeMap.get(linkKey.teNodeKey());
        if (intNode != null
                && CollectionUtils.isNotEmpty(intNode.teLinkTpKeys())) {
            intNode.setChildUpdate(true);
            intNode.teLinkTpKeys().remove(linkKey);
        }
        // Then remove it from teLinkMap
        InternalTeLink link = teLinkMap.remove(linkKey);
        if (teLinkRemove && link != null) {
            // Remove it from networkLinkMap
            removeNetworkLink(link.networkLinkKey(), teLinkRemove);
        }
    }

    @Override
    public void removeTeLink(TeLinkTpGlobalKey linkKey) {
        removeTeLink(linkKey, true);
    }

    private NetworkLink networkLink(NetworkLinkKey linkKey,
                                    InternalNetworkLink intLink) {
        if (intLink == null) {
            return null;
        }
        return new DefaultNetworkLink(linkKey.linkId(), intLink.source(),
                                      intLink.destination(),
                                      intLink.supportingLinkIds(),
                                      teLink(intLink.teLinkKey()));
    }

    @Override
    public NetworkLink networkLink(NetworkLinkKey linkKey) {
        InternalNetworkLink intLink = networkLinkMap.get(linkKey);
        return networkLink(linkKey, intLink);
    }

    private void updateNetworkLink(NetworkLinkKey linkKey, NetworkLink link,
                                   boolean parentUpdate, boolean teLinkUpdate,
                                   TeLinkTpGlobalKey teLinkKey) {
        InternalNetwork intNework = null;
        if (!parentUpdate) {
            intNework = networkMap.get(linkKey.networkId());
            if (intNework == null) {
                log.error("Network is not in dataStore for linkUpdate {}",
                          linkKey);
                return;
            }
        }

        InternalNetworkLink exLink = networkLinkMap.get(linkKey);

        // Now update teLinkMap first
        if (!teLinkUpdate && teLinkKey != null) {
            updateTeLink(teLinkKey, link.teLink(), parentUpdate, teLinkUpdate,
                         linkKey);
        }
        // Update networkLinkMap
        InternalNetworkLink intLink = new InternalNetworkLink(link,
                                                              parentUpdate);
        intLink.setTeLinkKey(teLinkKey);
        networkLinkMap.put(linkKey, intLink);
        if (exLink == null && !parentUpdate && intNework != null) {
            // Update the InternalNetwork
            intNework.setChildUpdate(true);
            TeUtils.addListElement(intNework.linkIds(), linkKey);
        }
    }

    @Override
    public void updateNetworkLink(NetworkLinkKey linkKey, NetworkLink link) {
        TeLinkTpGlobalKey teLinkKey = null;
        if (link.teLink() != null) {
            teLinkKey = new TeLinkTpGlobalKey(networkMap
                    .get(linkKey.networkId()).teTopologyKey(),
                                              link.teLink().teLinkKey());
        }

        updateNetworkLink(linkKey, link, false, false, teLinkKey);
    }

    private void removeNetworkLink(NetworkLinkKey linkKey,
                                   boolean teLinkRemove) {
        // Update the InternalNetwork
        InternalNetwork intNework = networkMap.get(linkKey.networkId());
        if (intNework != null
                && CollectionUtils.isNotEmpty(intNework.linkIds())) {
            intNework.setChildUpdate(true);
            intNework.linkIds().remove(linkKey.linkId());
        }
        // Remove it from networkLinkMap
        InternalNetworkLink intLink = networkLinkMap.remove(linkKey);
        if (!teLinkRemove && intLink != null && intLink.teLinkKey() != null) {
            // Now remove it from teLinkMap
            removeTeLink(intLink.teLinkKey(), teLinkRemove);
        }
    }

    @Override
    public void removeNetworkLink(NetworkLinkKey linkKey) {
        removeNetworkLink(linkKey, false);
    }

    private TerminationPoint terminationPoint(TerminationPointKey tpKey) {
        InternalTerminationPoint intTp = tpMap.get(tpKey);
        if (intTp == null) {
            return null;
        }
        return new DefaultTerminationPoint(tpKey.tpId(),
                                           intTp.supportingTpIds(),
                                           intTp.teTpKey().teLinkTpId());
    }

    private void updateTerminationPoint(TerminationPointKey tpKey,
                                        TerminationPoint tp,
                                        boolean parentUpdate,
                                        TeNodeKey teNodeKey) {
        TeNodeKey myTeNodeKey;
        InternalNetworkNode intNode = null;
        if (!parentUpdate) {
            intNode = networkNodeMap.get(tpKey.nodeId());
            if (intNode == null) {
                log.error(" node is not in dataStore for tp update {}", tpKey);
                return;
            }
            myTeNodeKey = intNode.teNodeKey();
        } else {
            myTeNodeKey = teNodeKey;
        }
        TeLinkTpGlobalKey teTpKey = new TeLinkTpGlobalKey(myTeNodeKey,
                                                          tp.teTpId());

        boolean newTp = tpMap.get(tpKey) == null;
        InternalTerminationPoint intTp = new InternalTerminationPoint(tp);
        intTp.setTeTpKey(teTpKey);
        tpMap.put(tpKey, intTp);
        if (newTp) {
            // Update tpKeyMap
            tpKeyMap.put(teTpKey, tpKey);
            if (!parentUpdate && intNode != null) {
                // Update InternalNetworkNode
                intNode.setChildUpdate(true);
                intNode.setTpIds(TeUtils.addListElement(intNode.tpIds(),
                                                        tpKey.tpId()));
            }
        }
    }

    @Override
    public void updateTerminationPoint(TerminationPointKey tpKey,
                                       TerminationPoint tp) {
        updateTerminationPoint(tpKey, tp, false, null);
    }

    @Override
    public void removeTerminationPoint(TerminationPointKey tpKey) {
        // Update InternalNetworkNode
        InternalNetworkNode intNode = networkNodeMap.get(tpKey.nodeId());
        if (intNode != null && CollectionUtils.isNotEmpty(intNode.tpIds())) {
            intNode.setChildUpdate(true);
            intNode.tpIds().remove(tpKey.tpId());
        }
        // Remove it from tpMap
        InternalTerminationPoint tp = tpMap.remove(tpKey);
        // Remove it from tpKeyMap
        if (tp != null) {
            tpKeyMap.remove(tp.teTpKey());
        }
    }

    @Override
    public TunnelTerminationPoint tunnelTerminationPoint(TtpKey ttpId) {
        return ttpMap.get(ttpId);
    }

    @Override
    public long nextTeTopologyId() {
        return 0;
    }

    @Override
    public long nextTeNodeId(TeTopologyKey topoKey) {
        return teTopologyMap.get(topoKey).nextTeNodeId();
    }

    @Override
    public void setNextTeNodeId(TeTopologyKey topoKey, long nextNodeId) {
        teTopologyMap.get(topoKey).setNextTeNodeId(nextNodeId);
    }

    @Override
    public KeyId networkId(TeTopologyKey teTopologyKey) {
        return teTopologyMap.get(teTopologyKey).topologyData().networkId();
    }

    @Override
    public NetworkNodeKey nodeKey(TeNodeKey teNodeKey) {
        return teNodeMap.get(teNodeKey).networkNodeKey();
    }

    @Override
    public NetworkLinkKey linkKey(TeLinkTpGlobalKey teLinkKey) {
        return teLinkMap.get(teLinkKey).networkLinkKey();
    }

    @Override
    public TerminationPointKey terminationPointKey(TeLinkTpGlobalKey teTpKey) {
        return tpKeyMap.get(teTpKey);
    }

    @Override
    public void setProviderId(long providerId) {
        this.providerId = providerId;
    }

    @Override
    public BlockingQueue<TeTopologyMapEvent> mapEventQueue() {
        return null;
    }
}

