package org.batfish.answerer;

import java.util.List;
import java.util.Map;
import java.util.function.Function;

import org.batfish.common.util.CommonUtil;
import org.batfish.datamodel.AsPathAccessList;
import org.batfish.datamodel.CommunityList;
import org.batfish.datamodel.Configuration;
import org.batfish.datamodel.IkeGateway;
import org.batfish.datamodel.RouteFilterList;
import org.batfish.datamodel.answers.AnswerElement;
import org.batfish.datamodel.answers.CompareSameNameAnswerElement;
import org.batfish.datamodel.collections.NamedStructureEquivalenceSets;
import org.batfish.datamodel.questions.CompareSameNameQuestion;
import org.batfish.datamodel.questions.Question;
import org.batfish.main.Batfish;
import org.batfish.main.Settings.TestrigSettings;

public class CompareSameNameAnswerer extends Answerer {

   private CompareSameNameAnswerElement _answerElement;

   private Map<String, Configuration> _configurations;

   private List<String> _nodes;

   public CompareSameNameAnswerer(Question question, Batfish batfish) {
      super(question, batfish);
   }

   private <T> void add(Class<T> structureClass,
         Function<Configuration, Map<String, T>> structureMapRetriever) {
      _answerElement.add(
            structureClass.getSimpleName(),
            processStructures(structureClass, _nodes, _configurations,
                  structureMapRetriever));
   }

   @Override
   public AnswerElement answer(TestrigSettings testrigSettings) {

      CompareSameNameQuestion question = (CompareSameNameQuestion) _question;
      _batfish.checkConfigurations(testrigSettings);
      _configurations = _batfish.loadConfigurations(testrigSettings);
      _answerElement = new CompareSameNameAnswerElement();
      // collect relevant nodes in a list.
      _nodes = CommonUtil.getMatchingStrings(question.getNodeRegex(),
            _configurations.keySet());

      add(AsPathAccessList.class, c -> c.getAsPathAccessLists());
      add(CommunityList.class, c -> c.getCommunityLists());
      add(IkeGateway.class, c -> c.getIkeGateways());
      add(RouteFilterList.class, c -> c.getRouteFilterLists());

      return _answerElement;
   }

   private <T> NamedStructureEquivalenceSets<T> processStructures(
         Class<T> structureClass, List<String> hostnames,
         Map<String, Configuration> configurations,
         Function<Configuration, Map<String, T>> structureMapRetriever) {
      NamedStructureEquivalenceSets<T> ae = new NamedStructureEquivalenceSets<T>(
            structureClass.getSimpleName());
      for (String hostname : hostnames) {
         // Process route filters
         Configuration node = configurations.get(hostname);
         Map<String, T> structureMap = structureMapRetriever.apply(node);
         for (String listName : structureMap.keySet()) {
            if (listName.startsWith("~")) {
               continue;
            }
            ae.add(hostname, listName, structureMap.get(listName));
         }
      }
      ae.clean();
      return ae;
   }

}

@@ -325,16 +325,266 @@
 ateway;%0A
+import org.batfish.datamodel.IkePolicy;%0Aimport org.batfish.datamodel.IkeProposal;%0Aimport org.batfish.datamodel.IpAccessList;%0Aimport org.batfish.datamodel.IpsecPolicy;%0Aimport org.batfish.datamodel.IpsecProposal;%0Aimport org.batfish.datamodel.IpsecVpn;%0A
 import o
@@ -917,32 +917,91 @@
 tions.Question;%0A
+import org.batfish.datamodel.routing_policy.RoutingPolicy;%0A
 import org.batfi
@@ -2381,56 +2381,451 @@
 add(
-RouteFilterList.class, c -%3E c.getRouteFilterList
+IkePolicy.class, c -%3E c.getIkePolicies());%0A      add(IkeProposal.class, c -%3E c.getIkeProposals());%0A      add(IpAccessList.class, c -%3E c.getIpAccessLists());%0A      add(IpsecPolicy.class, c -%3E c.getIpsecPolicies());%0A      add(IpsecProposal.class, c -%3E c.getIpsecProposals());%0A      add(IpsecVpn.class, c -%3E c.getIpsecVpns());%0A      add(RouteFilterList.class, c -%3E c.getRouteFilterLists());%0A      add(RoutingPolicy.class, c -%3E c.getRoutingPolicie
 s())

add structures to comparesamenameanswerer