class RoutesAnswererUtil {

  static Map<RouteRowKey, Map<RouteRowSecondaryKey, SortedSet<RouteRowAttribute>>> groupBgpRoutes(
      Table<String, String, Set<Bgpv4Route>> bgpRoutes,
      Set<String> matchingNodes,
      String vrfRegex,
      @Nullable Prefix network,
      String protocolRegex) {
    Map<RouteRowKey, Map<RouteRowSecondaryKey, SortedSet<RouteRowAttribute>>> routesGroups =
        new HashMap<>();
    Pattern compiledProtocolRegex = Pattern.compile(protocolRegex, Pattern.CASE_INSENSITIVE);
    Pattern compiledVrfRegex = Pattern.compile(vrfRegex);
    matchingNodes.forEach(
        hostname ->
            bgpRoutes
                .row(hostname)
                .forEach(
                    (vrfName, routes) -> {
                      if (compiledVrfRegex.matcher(vrfName).matches()) {
                        routes.stream()
                            .filter(
                                route ->
                                    (network == null || network.equals(route.getNetwork()))
                                        && compiledProtocolRegex
                                            .matcher(route.getProtocol().protocolName())
                                            .matches())
                            .forEach(
                                route ->
                                    routesGroups
                                        .computeIfAbsent(
                                            new RouteRowKey(hostname, vrfName, route.getNetwork()),
                                            k -> new HashMap<>())
                                        .computeIfAbsent(
                                            new RouteRowSecondaryKey(
                                                route.getNextHopIp(),
                                                route.getProtocol().protocolName()),
                                            k -> new TreeSet<>())
                                        .add(
                                            RouteRowAttribute.builder()
                                                .setOriginProtocol(
                                                    route.getSrcProtocol() != null
                                                        ? route.getSrcProtocol().protocolName()
                                                        : null)
                                                .setAdminDistance(route.getAdministrativeCost())
                                                .setMetric(route.getMetric())
                                                .setAsPath(route.getAsPath())
                                                .setLocalPreference(route.getLocalPreference())
                                                .setCommunities(
                                                    route.getCommunities().getCommunities().stream()
                                                        .map(Community::toString)
                                                        .collect(toImmutableList()))
                                                .setOriginType(route.getOriginType())
                                                .setTag(
                                                    route.getTag() == Route.UNSET_ROUTE_TAG
                                                        ? null
                                                        : route.getTag())
                                                .build()));
                      }
                    }));

    return routesGroups;
  }

}