/*
 * 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.bgp.cli;

import org.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.onosproject.bgp.controller.BgpController;
import org.onosproject.bgp.controller.BgpLocalRib;
import org.onosproject.bgpio.protocol.BgpLSNlri;

import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSIdentifier;
import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetails;
import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetailsLocalRib;
import org.onosproject.bgpio.protocol.linkstate.BgpLinkLSIdentifier;
import org.onosproject.bgpio.protocol.linkstate.BgpPrefixLSIdentifier;
import org.onosproject.bgpio.protocol.linkstate.NodeDescriptors;
import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
import org.onosproject.bgpio.types.IPv4AddressTlv;
import org.onosproject.bgpio.types.RouteDistinguisher;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.LinkStateAttributes;
import org.onosproject.bgpio.types.MpReachNlri;
import org.onosproject.bgpio.types.AutonomousSystemTlv;
import org.onosproject.bgpio.types.IsIsNonPseudonode;
import org.onosproject.bgpio.types.LocalPref;
import org.onosproject.bgpio.types.Origin;
import org.onosproject.bgpio.types.attr.BgpAttrRouterIdV4;
import org.onosproject.bgpio.types.attr.BgpLinkAttrMaxLinkBandwidth;
import org.onosproject.bgpio.types.attr.BgpLinkAttrUnRsrvdLinkBandwidth;
import org.onosproject.bgpio.types.attr.BgpLinkAttrTeDefaultMetric;
import org.onosproject.bgpio.types.attr.BgpLinkAttrIgpMetric;
import org.onosproject.cli.AbstractShellCommand;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;
import java.util.Set;
import java.util.List;
import java.util.Iterator;
import java.util.Arrays;


@Service
@Command(scope = "onos", name = "bgp-rib", description = "lists RIB configuration")
public class BgpLocalRibDisplay extends AbstractShellCommand {
    private static final Logger log = LoggerFactory.getLogger(BgpLocalRibDisplay.class);
    private static final String NODETREE = "nodes";
    private static final String LINKTREE = "links";
    private static final String PREFIXTREE = "prefix";
    private static final String VPNNODETREE = "vpnnodes";
    private static final String VPNLINKTREE = "vpnlinkS";
    private static final String VPNPREFIXTREE = "vpnprefix";
    protected Origin origin;
    protected LocalPref localPref;
    protected BgpAttrRouterIdV4 bgpAttrRouterIdV4;
    protected IsIsNonPseudonode isIsNonPseudonode;
    protected AutonomousSystemTlv autonomousSystemTlv;
    protected IPv4AddressTlv iPv4AddressTlv;
    protected BgpLinkAttrMaxLinkBandwidth bgpLinkAttrMaxLinkBandwidth;
    protected BgpLinkAttrUnRsrvdLinkBandwidth bgpLinkAttrUnRsrvdLinkBandwidth;
    protected BgpLinkAttrTeDefaultMetric bgpLinkAttrTeDefaultMetric;
    protected BgpLinkAttrIgpMetric bgpLinkAttrIgpMetric;
    protected PathAttrNlriDetailsLocalRib pathAttrNlriDetailsLocalRib;
    protected MpReachNlri mpReachNlri;
    protected PathAttrNlriDetails pathAttrNlriDetails;
    protected BgpNodeLSNlriVer4.ProtocolType protocolType;
    protected BgpController bgpController = get(BgpController.class);
    protected BgpLocalRib bgpLocalRib = bgpController.bgpLocalRib();
    Map<BgpNodeLSIdentifier, PathAttrNlriDetailsLocalRib> nodeTreeMap = bgpLocalRib.nodeTree();
    Set<BgpNodeLSIdentifier> nodekeySet = nodeTreeMap.keySet();
    Map<BgpLinkLSIdentifier, PathAttrNlriDetailsLocalRib> linkTreeMap = bgpLocalRib.linkTree();
    Set<BgpLinkLSIdentifier> linkkeySet = linkTreeMap.keySet();
    @Argument(index = 0, name = "name",
            description = "nodetree" + "\n" + "linktree" + "\n" + "prefixtree" + "\n" + "vpnnodetree" + "\n" +
                    "vpnlinktree" + "\n" + "vpnprefixtree", required = true, multiValued = false)
    String name = null;
    @Argument(index = 1, name = "numberofentries",
            description = "numberofentries", required = false, multiValued = false)
    int numberofentries;
    @Argument(index = 2, name = "vpnId",
            description = "vpnId", required = false, multiValued = false)
    String vpnId = null;
    private int count = 0;

    @Override
    protected void doExecute() {
        switch (name) {
            case NODETREE:
                displayNodes();
                break;
            case LINKTREE:
                displayLinks();
                break;
            case PREFIXTREE:
                displayPrefix();
                break;
            case VPNNODETREE:
                displayVpnNodes();
                break;
            case VPNLINKTREE:
                displayVpnLinks();
                break;
            case VPNPREFIXTREE:
                displayVpnPrefix();
                break;
            default:
                System.out.print("Unknown Command");
                break;
        }

    }

    private void displayNodes() {
        try {
            int counter = 0;
            print("Total number of entries = %s", nodeTreeMap.size());
            for (BgpNodeLSIdentifier nodes : nodekeySet) {
                if (numberofentries > nodeTreeMap.size() || numberofentries < 0) {
                    System.out.print("Wrong Argument");
                    break;
                } else if (counter < numberofentries) {
                    pathAttrNlriDetailsLocalRib = nodeTreeMap.get(nodes);
                    displayNode();
                    counter++;
                } else if (counter == 0) {
                    pathAttrNlriDetailsLocalRib = nodeTreeMap.get(nodes);
                    displayNode();


                }

            }
        } catch (Exception e) {
            log.debug("Error occurred while displaying BGP nodes: {}", e.getMessage());
        }

    }


    private void displayLinks() {
        try {
            int counter = 0;
            print("Total Number of entries = %d", linkTreeMap.size());
            for (BgpLinkLSIdentifier links : linkkeySet) {
                if (numberofentries > linkTreeMap.size() || numberofentries < 0) {
                    System.out.print("Wrong Argument");
                    break;
                } else if (counter < numberofentries) {
                    pathAttrNlriDetailsLocalRib = linkTreeMap.get(links);
                    print("Total number of entries = %d", linkTreeMap.size());
                    displayLink();
                    counter++;
                } else if (counter == 0) {
                    pathAttrNlriDetailsLocalRib = linkTreeMap.get(links);
                    displayLink();
                }

            }
        } catch (Exception e) {
            log.debug("Error occurred while displaying BGP links: {}", e.getMessage());
        }
    }

    private void displayPrefix() {
        try {
            this.bgpController = get(BgpController.class);
            bgpLocalRib = bgpController.bgpLocalRib();
            Map<BgpPrefixLSIdentifier, PathAttrNlriDetailsLocalRib> prefixmap = bgpLocalRib.prefixTree();
            Set<BgpPrefixLSIdentifier> prefixkeySet = prefixmap.keySet();
            for (BgpPrefixLSIdentifier prefix : prefixkeySet) {
                pathAttrNlriDetailsLocalRib = prefixmap.get(prefix);
                pathAttrNlriDetails = pathAttrNlriDetailsLocalRib.localRibNlridetails();
                print("No of entries = %d", prefixmap.size());
                System.out.print(pathAttrNlriDetailsLocalRib.toString());

            }


        } catch (Exception e) {
            log.debug("Error occurred while displaying BGP prefixes: {}", e.getMessage());

        }
    }

    private void displayVpnNodes() {
        try {
            this.bgpController = get(BgpController.class);
            bgpLocalRib = bgpController.bgpLocalRib();
            Map<RouteDistinguisher, Map<BgpNodeLSIdentifier, PathAttrNlriDetailsLocalRib>> vpnNode =
                    bgpLocalRib.vpnNodeTree();
            Set<RouteDistinguisher> vpnNodekeySet = vpnNode.keySet();
            for (RouteDistinguisher vpnNodes : vpnNodekeySet) {
                boolean invalidProcess = true;
                if (vpnId != null && Integer.parseInt(vpnId.trim()) == vpnNodes.hashCode()) {
                    invalidProcess = false;
                    displayNodes();
                }
                if (invalidProcess) {
                    print("%s\n", "Id " + vpnId + "does not exist...!!!");
                }
            }
        } catch (Exception e) {
            log.debug("Error occurred while displaying BGP nodes based on VPN : {}", e.getMessage());
        }

    }

    private void displayVpnLinks() {
        try {
            this.bgpController = get(BgpController.class);
            bgpLocalRib = bgpController.bgpLocalRib();
            Map<RouteDistinguisher, Map<BgpLinkLSIdentifier, PathAttrNlriDetailsLocalRib>> vpnLink =
                    bgpLocalRib.vpnLinkTree();
            Set<RouteDistinguisher> vpnLinkkeySet = vpnLink.keySet();
            for (RouteDistinguisher vpnLinks : vpnLinkkeySet) {
                boolean invalidProcess = true;
                if (vpnId != null && Integer.parseInt(vpnId.trim()) == vpnLinks.hashCode()) {
                    invalidProcess = false;
                    displayLinks();
                }
                if (invalidProcess) {
                    print("%s\n", "Id " + vpnId + "does not exist...!!!");
                }
            }
        } catch (Exception e) {
            log.debug("Error occurred while displaying BGP links based on VPN : {}", e.getMessage());
        }
    }

    private void displayVpnPrefix() {
        try {
            this.bgpController = get(BgpController.class);
            bgpLocalRib = bgpController.bgpLocalRib();
            Map<RouteDistinguisher, Map<BgpPrefixLSIdentifier, PathAttrNlriDetailsLocalRib>> vpnPrefix =
                    bgpLocalRib.vpnPrefixTree();
            Set<RouteDistinguisher> vpnPrefixkeySet = vpnPrefix.keySet();
            for (RouteDistinguisher vpnprefixId : vpnPrefixkeySet) {
                boolean invalidProcess = true;
                if (vpnId != null && Integer.parseInt(vpnId.trim()) == vpnprefixId.hashCode()) {
                    invalidProcess = false;
                    displayPrefix();
                }
                if (invalidProcess) {
                    print("%s\n", "Id " + vpnId + "does not exist...!!!");
                }
            }
        } catch (Exception e) {
            log.debug("Error occurred while displaying BGP prefixes based on VPN : {}", e.getMessage());
        }
    }

    private void displayNode() {


        pathAttrNlriDetails = pathAttrNlriDetailsLocalRib.localRibNlridetails();
        List<BgpValueType> bgpValueTypeList = pathAttrNlriDetails.pathAttributes();
        protocolType = pathAttrNlriDetails.protocolID();
        Iterator<BgpValueType> itrBgpValueType = bgpValueTypeList.iterator();
        while (itrBgpValueType.hasNext()) {
            BgpValueType bgpValueType = itrBgpValueType.next();
            if (bgpValueType instanceof Origin) {
                origin = (Origin) bgpValueType;
            } else if (bgpValueType instanceof LocalPref) {
                localPref = (LocalPref) bgpValueType;
            } else if (bgpValueType instanceof LinkStateAttributes) {
                LinkStateAttributes linkStateAttributes = (LinkStateAttributes) bgpValueType;
                List linkStateAttribiuteList = linkStateAttributes.linkStateAttributes();
                Iterator<BgpValueType> linkStateAttribiteIterator = linkStateAttribiuteList.iterator();
                while (linkStateAttribiteIterator.hasNext()) {
                    BgpValueType bgpValueType1 = linkStateAttribiteIterator.next();
                    if (bgpValueType1 instanceof BgpAttrRouterIdV4) {
                        bgpAttrRouterIdV4 = (BgpAttrRouterIdV4) bgpValueType1;
                    }
                }
            } else if (bgpValueType instanceof MpReachNlri) {
                mpReachNlri = (MpReachNlri) bgpValueType;
                List<BgpLSNlri> bgpLSNlris = mpReachNlri.mpReachNlri();
                Iterator<BgpLSNlri> bgpLsnlrisIterator = bgpLSNlris.iterator();
                while (bgpLsnlrisIterator.hasNext()) {
                    BgpLSNlri bgpLSNlri = bgpLsnlrisIterator.next();
                    if (bgpLSNlri instanceof BgpNodeLSNlriVer4) {
                        BgpNodeLSNlriVer4 bgpNodeLSNlriVer4 = (BgpNodeLSNlriVer4) bgpLSNlri;
                        BgpNodeLSIdentifier bgpNodeLSIdentifier = bgpNodeLSNlriVer4.getLocalNodeDescriptors();
                        NodeDescriptors nodeDescriptors = bgpNodeLSIdentifier.getNodedescriptors();
                        List<BgpValueType> bgpvalueTypesList = nodeDescriptors.getSubTlvs();
                        Iterator<BgpValueType> bgpValueTypeIterator = bgpvalueTypesList.iterator();
                        while (bgpValueTypeIterator.hasNext()) {
                            BgpValueType valueType = bgpValueTypeIterator.next();
                            if (valueType instanceof IsIsNonPseudonode) {
                                isIsNonPseudonode = (IsIsNonPseudonode) valueType;

                            }
                        }
                    }
                }
            }
        }
        print("RibAsNumber = %s,PeerIdentifier = %s,RibIpAddress = %s,ProtocolType = %s,Origin = %s,LocalPref = %s," +
                        "RouterID = %s,IsoNodeID = %s,NextHop = %s", pathAttrNlriDetailsLocalRib.localRibAsNum(),
                pathAttrNlriDetailsLocalRib.localRibIdentifier(), pathAttrNlriDetailsLocalRib.localRibIpAddress(),
                protocolType.toString(), origin.origin(), localPref.localPref(), bgpAttrRouterIdV4.attrRouterId(),
                Arrays.toString(isIsNonPseudonode.getIsoNodeId()), mpReachNlri.nexthop());
    }

    private void displayLink() {

        pathAttrNlriDetails = pathAttrNlriDetailsLocalRib.localRibNlridetails();
        List<BgpValueType> valueTypes = pathAttrNlriDetails.pathAttributes();
        Iterator<BgpValueType> itrBgpValueType = valueTypes.iterator();
        while (itrBgpValueType.hasNext()) {
            BgpValueType bgpValueType = itrBgpValueType.next();
            if (bgpValueType instanceof Origin) {
                origin = (Origin) bgpValueType;
            } else if (bgpValueType instanceof LocalPref) {
                localPref = (LocalPref) bgpValueType;
            } else if (bgpValueType instanceof LinkStateAttributes) {
                LinkStateAttributes linkStateAttributes = (LinkStateAttributes) bgpValueType;
                List linkStateAttributelist = linkStateAttributes.linkStateAttributes();
                Iterator<BgpValueType> linkStateAttributeIterator = linkStateAttributelist.iterator();
                while (linkStateAttributeIterator.hasNext()) {
                    BgpValueType bgpValueType1 = linkStateAttributeIterator.next();
                    if (bgpValueType1 instanceof BgpAttrRouterIdV4) {
                        bgpAttrRouterIdV4 = (BgpAttrRouterIdV4) bgpValueType1;
                    } else if (bgpValueType1 instanceof BgpLinkAttrMaxLinkBandwidth) {
                        bgpLinkAttrMaxLinkBandwidth = (BgpLinkAttrMaxLinkBandwidth) bgpValueType1;
                    } else if (bgpValueType1 instanceof BgpLinkAttrUnRsrvdLinkBandwidth) {
                        bgpLinkAttrUnRsrvdLinkBandwidth = (BgpLinkAttrUnRsrvdLinkBandwidth) bgpValueType1;
                    } else if (bgpValueType1 instanceof BgpLinkAttrTeDefaultMetric) {
                        bgpLinkAttrTeDefaultMetric = (BgpLinkAttrTeDefaultMetric) bgpValueType1;
                    } else if (bgpValueType1 instanceof BgpLinkAttrIgpMetric) {
                        bgpLinkAttrIgpMetric = (BgpLinkAttrIgpMetric) bgpValueType1;
                    }

                }
            } else if (bgpValueType instanceof MpReachNlri) {
                mpReachNlri = (MpReachNlri) bgpValueType;
                List<BgpLSNlri> bgpLSNlris = mpReachNlri.mpReachNlri();
                Iterator<BgpLSNlri> bgpLsnlrisIterator = bgpLSNlris.iterator();
                while (bgpLsnlrisIterator.hasNext()) {
                    BgpLSNlri bgpLSNlri = bgpLsnlrisIterator.next();
                    if (bgpLSNlri instanceof BgpLinkLsNlriVer4) {
                        BgpLinkLsNlriVer4 bgpLinkLsNlriVer4 = (BgpLinkLsNlriVer4) bgpLSNlri;
                        BgpLinkLSIdentifier bgpLinkLSIdentifier = bgpLinkLsNlriVer4.getLinkIdentifier();
                        NodeDescriptors localnodeDescriptors = bgpLinkLSIdentifier.localNodeDescriptors();
                        NodeDescriptors remotenodeDescriptors = bgpLinkLSIdentifier.remoteNodeDescriptors();
                        List<BgpValueType> linkDescriptors = bgpLinkLSIdentifier.linkDescriptors();
                        List<BgpValueType> subTlvList = localnodeDescriptors.getSubTlvs();
                        Iterator<BgpValueType> subTlvIterator = subTlvList.iterator();
                        while (subTlvIterator.hasNext()) {
                            BgpValueType valueType = subTlvIterator.next();
                            if (valueType instanceof IsIsNonPseudonode) {
                                isIsNonPseudonode = (IsIsNonPseudonode) valueType;
                            } else if (valueType instanceof AutonomousSystemTlv) {
                                autonomousSystemTlv = (AutonomousSystemTlv) valueType;
                            }
                        }
                        List<BgpValueType> remotevalueTypes = remotenodeDescriptors.getSubTlvs();
                        Iterator<BgpValueType> remoteValueTypesIterator = remotevalueTypes.iterator();
                        while (remoteValueTypesIterator.hasNext()) {
                            BgpValueType valueType = remoteValueTypesIterator.next();
                            if (valueType instanceof IsIsNonPseudonode) {
                                isIsNonPseudonode = (IsIsNonPseudonode) valueType;
                            } else if (valueType instanceof AutonomousSystemTlv) {
                                autonomousSystemTlv = (AutonomousSystemTlv) valueType;
                            }
                        }
                        Iterator<BgpValueType> listIterator = linkDescriptors.iterator();
                        while (listIterator.hasNext()) {
                            BgpValueType valueType = listIterator.next();
                            if (valueType instanceof IPv4AddressTlv) {
                                iPv4AddressTlv = (IPv4AddressTlv) valueType;
                            }

                        }
                    }
                }
            }
        }
        print("PeerIdentifier = %s,Origin = %s,LocalPref = %s,RouterID = %s,MaxBandwidth = %s," +
                        "UnreservedBandwidth = %s,DefaultMetric = %s,IGPMetric = %s,IsoNodeID = %s,ASNum = %s," +
                        "IPAddress = %s,NextHop = %s", pathAttrNlriDetailsLocalRib.localRibIdentifier(),
                origin.origin(), localPref.localPref(), bgpAttrRouterIdV4.attrRouterId(),
                bgpLinkAttrMaxLinkBandwidth.linkAttrMaxLinkBandwidth(),
                bgpLinkAttrUnRsrvdLinkBandwidth.getLinkAttrUnRsrvdLinkBandwidth().toString(),
                bgpLinkAttrTeDefaultMetric.attrLinkDefTeMetric(), bgpLinkAttrIgpMetric.attrLinkIgpMetric(),
                Arrays.toString(isIsNonPseudonode.getIsoNodeId()), autonomousSystemTlv.getAsNum(),
                iPv4AddressTlv.address(), mpReachNlri.nexthop().toString(),
                pathAttrNlriDetailsLocalRib.localRibIpAddress(), origin.origin(), localPref.localPref(),
                bgpAttrRouterIdV4.attrRouterId());

    }
}
