/*
 * 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.nexthop4());
    }

    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.nexthop4().toString(),
                pathAttrNlriDetailsLocalRib.localRibIpAddress(), origin.origin(), localPref.localPref(),
                bgpAttrRouterIdV4.attrRouterId());

    }
}