/*
 * Copyright 2014 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.sdnip.cli;

import java.util.ArrayList;
import java.util.Collection;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.sdnip.SdnIpService;
import org.onosproject.sdnip.bgp.BgpConstants.Update;
import org.onosproject.sdnip.bgp.BgpRouteEntry;
import org.onosproject.sdnip.bgp.BgpSession;

/**
 * Command to show the routes learned through BGP.
 */
@Command(scope = "onos", name = "bgp-routes",
         description = "Lists all BGP best routes")
public class BgpRoutesListCommand extends AbstractShellCommand {
    @Option(name = "-s", aliases = "--summary",
            description = "BGP routes summary",
            required = false, multiValued = false)
    private boolean routesSummary = false;

    @Option(name = "-n", aliases = "--neighbor",
            description = "Routes from a BGP neighbor",
            required = false, multiValued = false)
    private String bgpNeighbor;

    private static final String FORMAT_SUMMARY_V4 =
        "Total BGP IPv4 routes = %d";
    private static final String FORMAT_SUMMARY_V6 =
        "Total BGP IPv6 routes = %d";
    private static final String FORMAT_HEADER =
        "   Network            Next Hop        Origin LocalPref       MED BGP-ID";
    private static final String FORMAT_ROUTE_LINE1 =
        "   %-18s %-15s %6s %9s %9s %-15s";
    private static final String FORMAT_ROUTE_LINE2 =
        "                      AsPath %s";

    @Override
    protected void execute() {
        SdnIpService service = get(SdnIpService.class);

        // Print summary of the routes
        if (routesSummary) {
            printSummary(service.getBgpRoutes4(), service.getBgpRoutes6());
            return;
        }

        BgpSession foundBgpSession = null;
        if (bgpNeighbor != null) {
            // Print the routes from a single neighbor (if found)
            for (BgpSession bgpSession : service.getBgpSessions()) {
                if (bgpSession.remoteInfo().bgpId().toString().equals(bgpNeighbor)) {
                    foundBgpSession = bgpSession;
                    break;
                }
            }
            if (foundBgpSession == null) {
                print("BGP neighbor %s not found", bgpNeighbor);
                return;
            }
        }

        // Print the routes
        if (foundBgpSession != null) {
            printRoutes(foundBgpSession.getBgpRibIn4(),
                        foundBgpSession.getBgpRibIn6());
        } else {
            printRoutes(service.getBgpRoutes4(), service.getBgpRoutes6());
        }
    }

    /**
     * Prints summary of the routes.
     *
     * @param routes4 the IPv4 routes
     * @param routes6 the IPv6 routes
     */
    private void printSummary(Collection<BgpRouteEntry> routes4,
                              Collection<BgpRouteEntry> routes6) {
        if (outputJson()) {
            ObjectMapper mapper = new ObjectMapper();
            ObjectNode result = mapper.createObjectNode();
            result.put("totalRoutes4", routes4.size());
            result.put("totalRoutes6", routes6.size());
            print("%s", result);
        } else {
            print(FORMAT_SUMMARY_V4, routes4.size());
            print(FORMAT_SUMMARY_V6, routes6.size());
        }
    }

    /**
     * Prints all routes.
     *
     * @param routes4 the IPv4 routes to print
     * @param routes6 the IPv6 routes to print
     */
    private void printRoutes(Collection<BgpRouteEntry> routes4,
                             Collection<BgpRouteEntry> routes6) {
        if (outputJson()) {
            ObjectMapper mapper = new ObjectMapper();
            ObjectNode result = mapper.createObjectNode();
            result.put("routes4", json(routes4));
            result.put("routes6", json(routes6));
            print("%s", result);
        } else {
            // The IPv4 routes
            print(FORMAT_HEADER);
            for (BgpRouteEntry route : routes4) {
                printRoute(route);
            }
            print(FORMAT_SUMMARY_V4, routes4.size());
            print("");                  // Empty separator line
            // The IPv6 routes
            print(FORMAT_HEADER);
            for (BgpRouteEntry route : routes6) {
                printRoute(route);
            }
            print(FORMAT_SUMMARY_V6, routes6.size());
        }
    }

    /**
     * Prints a BGP route.
     *
     * @param route the route to print
     */
    private void printRoute(BgpRouteEntry route) {
        if (route != null) {
            print(FORMAT_ROUTE_LINE1, route.prefix(), route.nextHop(),
                  Update.Origin.typeToString(route.getOrigin()),
                  route.getLocalPref(), route.getMultiExitDisc(),
                  route.getBgpSession().remoteInfo().bgpId());
            print(FORMAT_ROUTE_LINE2, asPath4Cli(route.getAsPath()));
        }
    }

    /**
     * Formats the AS Path as a string that can be shown on the CLI.
     *
     * @param asPath the AS Path to format
     * @return the AS Path as a string
     */
    private String asPath4Cli(BgpRouteEntry.AsPath asPath) {
        ArrayList<BgpRouteEntry.PathSegment> pathSegments =
            asPath.getPathSegments();

        if (pathSegments.isEmpty()) {
            return "[none]";
        }

        final StringBuilder builder = new StringBuilder();
        for (BgpRouteEntry.PathSegment pathSegment : pathSegments) {
            String prefix = null;
            String suffix = null;
            switch (pathSegment.getType()) {
            case Update.AsPath.AS_SET:
                prefix = "[AS-Set";
                suffix = "]";
                break;
            case Update.AsPath.AS_SEQUENCE:
                break;
            case Update.AsPath.AS_CONFED_SEQUENCE:
                prefix = "[AS-Confed-Seq";
                suffix = "]";
                break;
            case Update.AsPath.AS_CONFED_SET:
                prefix = "[AS-Confed-Set";
                suffix = "]";
                break;
            default:
                builder.append(String.format("(type = %s)",
                        Update.AsPath.typeToString(pathSegment.getType())));
                break;
            }

            if (prefix != null) {
                if (builder.length() > 0) {
                    builder.append(" ");        // Separator
                }
                builder.append(prefix);
            }
            // Print the AS numbers
            for (Long asn : pathSegment.getSegmentAsNumbers()) {
                if (builder.length() > 0) {
                    builder.append(" ");        // Separator
                }
                builder.append(String.format("%d", asn));
            }
            if (suffix != null) {
                // No need for separator
                builder.append(prefix);
            }
        }
        return builder.toString();
    }

    /**
     * Produces a JSON array of routes.
     *
     * @param routes the routes with the data
     * @return JSON array with the routes
     */
    private JsonNode json(Collection<BgpRouteEntry> routes) {
        ObjectMapper mapper = new ObjectMapper();
        ArrayNode result = mapper.createArrayNode();

        for (BgpRouteEntry route : routes) {
            result.add(json(mapper, route));
        }
        return result;
    }

    /**
     * Produces JSON object for a route.
     *
     * @param mapper the JSON object mapper to use
     * @param route the route with the data
     * @return JSON object for the route
     */
    private ObjectNode json(ObjectMapper mapper, BgpRouteEntry route) {
        ObjectNode result = mapper.createObjectNode();

        result.put("prefix", route.prefix().toString());
        result.put("nextHop", route.nextHop().toString());
        result.put("bgpId",
                   route.getBgpSession().remoteInfo().bgpId().toString());
        result.put("origin", Update.Origin.typeToString(route.getOrigin()));
        result.put("asPath", json(mapper, route.getAsPath()));
        result.put("localPref", route.getLocalPref());
        result.put("multiExitDisc", route.getMultiExitDisc());

        return result;
    }

    /**
     * Produces JSON object for an AS path.
     *
     * @param mapper the JSON object mapper to use
     * @param asPath the AS path with the data
     * @return JSON object for the AS path
     */
    private ObjectNode json(ObjectMapper mapper, BgpRouteEntry.AsPath asPath) {
        ObjectNode result = mapper.createObjectNode();
        ArrayNode pathSegmentsJson = mapper.createArrayNode();
        for (BgpRouteEntry.PathSegment pathSegment : asPath.getPathSegments()) {
            ObjectNode pathSegmentJson = mapper.createObjectNode();
            pathSegmentJson.put("type",
                                Update.AsPath.typeToString(pathSegment.getType()));
            ArrayNode segmentAsNumbersJson = mapper.createArrayNode();
            for (Long asNumber : pathSegment.getSegmentAsNumbers()) {
                segmentAsNumbersJson.add(asNumber);
            }
            pathSegmentJson.put("segmentAsNumbers", segmentAsNumbersJson);
            pathSegmentsJson.add(pathSegmentJson);
        }
        result.put("pathSegments", pathSegmentsJson);

        return result;
    }
}
