class BgpSessionStatusAnswerer extends Answerer {

  @Nonnull
  @VisibleForTesting
  static Row getActivePeerRow(
      BgpPeerConfigId activeId,
      BgpActivePeerConfig activePeer,
      Map<Ip, Map<String, Set<String>>> ipVrfOwners,
      ValueGraph<BgpPeerConfigId, BgpSessionProperties> configuredTopology,
      ValueGraph<BgpPeerConfigId, BgpSessionProperties> establishedTopology) {
    SessionType type = getSessionType(activePeer);

    // Check topologies to determine the peer's status and, if applicable, remote node
    BgpSessionStatus status = NOT_COMPATIBLE;
    Node remoteNode = null;
    Long localAs = activePeer.getLocalAs();
    String remoteAs = activePeer.getRemoteAsns().toString();
    Set<Type> addressFamilies = ImmutableSet.of();
    if (establishedTopology.nodes().contains(activeId)
        && establishedTopology.outDegree(activeId) == 1) {
      status = ESTABLISHED;
      /*
      Find the remote node with which the session was established. Note that this is NOT necessarily
      the same as the remote node we would find from the configured topology, because the peer could
      have multiple compatible remotes of which only one turned out to be reachable.
       */
      BgpPeerConfigId remoteId = establishedTopology.adjacentNodes(activeId).iterator().next();
      String remoteNodeName = remoteId.getHostname();
      remoteNode = new Node(remoteNodeName);
      localAs = getLocalAs(establishedTopology, activeId, remoteId, activePeer);
      remoteAs = getRemoteAs(establishedTopology, activeId, remoteId, activePeer);
      addressFamilies = getAddressFamilies(establishedTopology, activeId, remoteId);

    } else if (getConfiguredStatus(activeId, activePeer, type, ipVrfOwners, configuredTopology)
        == UNIQUE_MATCH) {
      status = NOT_ESTABLISHED;
      // This peer has a unique match, but it's unreachable. Show that remote peer's node.
      BgpPeerConfigId remoteId = configuredTopology.adjacentNodes(activeId).iterator().next();
      String remoteNodeName = remoteId.getHostname();
      remoteNode = new Node(remoteNodeName);
      localAs = getLocalAs(configuredTopology, activeId, remoteId, activePeer);
      remoteAs = getRemoteAs(configuredTopology, activeId, remoteId, activePeer);
      addressFamilies = getAddressFamilies(configuredTopology, activeId, remoteId);
    }
    return Row.builder(METADATA_MAP)
        .put(COL_ESTABLISHED_STATUS, status)
        .put(COL_ADDRESS_FAMILIES, addressFamilies)
        .put(COL_LOCAL_INTERFACE, null)
        .put(COL_LOCAL_AS, localAs)
        .put(COL_LOCAL_IP, activePeer.getLocalIp())
        .put(COL_NODE, new Node(activeId.getHostname()))
        .put(COL_REMOTE_AS, remoteAs)
        .put(COL_REMOTE_NODE, remoteNode)
        .put(COL_REMOTE_INTERFACE, null)
        .put(COL_REMOTE_IP, new SelfDescribingObject(Schema.IP, activePeer.getPeerAddress()))
        .put(COL_SESSION_TYPE, getSessionType(activePeer))
        .put(COL_VRF, activeId.getVrfName())
        .build();
  }

  public  BgpSessionStatusAnswerer(Question question, IBatfish batfish);

}