// Path: src/main/java/com/homeadvisor/kafdrop/model/ConsumerTopicVO.java
// public class ConsumerTopicVO
// {
//    private final String topic;
//    private final String groupId;
//    private final Map<Integer, ConsumerPartitionVO> offsets = new TreeMap<>();
// 
//    public ConsumerTopicVO(String topic, String groupId)
//    {
//       this.topic = topic;
//       this.groupId = groupId;
//    }
// 
//    public String getTopic()
//    {
//       return topic;
//    }
// 
//    public void addOffset(ConsumerPartitionVO offset)
//    {
//       offsets.put(offset.getPartitionId(), offset);
//    }
// 
//    public long getLag()
//    {
//       return offsets.values().stream()
//          .map(ConsumerPartitionVO::getLag)
//          .filter(lag -> lag >= 0)
//          .reduce(0L, Long::sum);
//    }
// 
//    public long getMaxLag()
//    {
//       return offsets.values().stream()
//          .map(ConsumerPartitionVO::getLag)
//          .filter(lag -> lag >= 0)
//          .reduce(0L, Long::max);
//    }
// 
//    public Collection<ConsumerPartitionVO> getPartitions()
//    {
//       return offsets.values();
//    }
// 
//    public ConsumerPartitionVO getPartition(int partitionId)
//    {
//       return offsets.get(partitionId);
//    }
// 
//    public ConsumerPartitionVO getOrCreatePartition(int partitionId)
//    {
//       return offsets.computeIfAbsent(partitionId, id -> new ConsumerPartitionVO(groupId, topic, id));
//    }
// 
//    public double getCoveragePercent()
//    {
//       return (offsets.size() > 0) ? ((double)getAssignedPartitionCount()) / offsets.size() : 0.0;
//    }
// 
//    public int getAssignedPartitionCount()
//    {
//       return (int) offsets.values().stream()
//          .filter(p -> p.getOwner() != null)
//          .count();
//    }
// 
//    public int getOwnerCount()
//    {
//       return (int)offsets.values().stream()
//          .map(ConsumerPartitionVO::getOwner)
//          .filter(Objects::nonNull)
//          .distinct()
//          .count();
//    }
// }
// 
// Path: src/main/java/com/homeadvisor/kafdrop/model/ConsumerVO.java
// public class ConsumerVO implements Comparable<ConsumerVO>
// {
//    private String groupId;
//    private Map<String, ConsumerTopicVO> topics = new TreeMap<>();
//    private List<ConsumerRegistrationVO> activeInstances = new ArrayList<>();
//    private boolean legacy = false;
// 
//    public ConsumerVO(String groupId)
//    {
//       Validate.notEmpty("groupId is required");
//       this.groupId = groupId;
//    }
// 
//    public boolean isLegacy()
//    {
//       return legacy;
//    }
// 
//    public void setLegacy(boolean legacy)
//    {
//       this.legacy = legacy;
//    }
// 
//    public String getGroupId()
//    {
//       return groupId;
//    }
// 
//    public void setGroupId(String groupId)
//    {
//       this.groupId = groupId;
//    }
// 
//    public void addActiveInstance(ConsumerRegistrationVO id)
//    {
//       activeInstances.add(id);
//    }
// 
//    public List<ConsumerRegistrationVO> getActiveInstances()
//    {
//       return activeInstances;
//    }
// 
//    public List<ConsumerRegistrationVO> getActiveInstancesForTopic(String topic)
//    {
//       return activeInstances.stream()
//          .filter(registration -> registration.subscribesToTopic(topic))
//          .collect(Collectors.toList());
//    }
// 
//    public void addTopic(ConsumerTopicVO topic)
//    {
//       topics.put(topic.getTopic(), topic);
//    }
// 
//    public ConsumerTopicVO getTopic(String topic)
//    {
//       return topics.get(topic);
//    }
// 
//    public ConsumerTopicVO getOrCreateTopic(String topic)
//    {
//       ConsumerTopicVO consumerTopic = getTopic(topic);
//       if (consumerTopic == null)
//       {
//          consumerTopic = new ConsumerTopicVO(topic, groupId);
//          addTopic(consumerTopic);
//       }
//       return consumerTopic;
//    }
// 
//    public Collection<ConsumerTopicVO> getTopics()
//    {
//       return topics.values();
//    }
// 
//    public int getActiveTopicCount()
//    {
//       return topics.values().stream()
//          .map(t -> t.getAssignedPartitionCount() > 0 ? 1 : 0)
//          .reduce(0, Integer::sum);
//    }
// 
//    @Override
//    public int compareTo(ConsumerVO that)
//    {
//       return this.groupId.compareTo(that.groupId);
//    }
// 
//    @Override
//    public boolean equals(Object o)
//    {
//       if (this == o) return true;
//       if (o == null || getClass() != o.getClass()) return false;
// 
//       ConsumerVO vo = (ConsumerVO) o;
// 
//       if (!groupId.equals(vo.groupId)) return false;
// 
//       return true;
//    }
// 
//    @Override
//    public int hashCode()
//    {
//       return groupId.hashCode();
//    }
// 
// }


import com.homeadvisor.kafdrop.model.ConsumerTopicVO;
import com.homeadvisor.kafdrop.model.ConsumerVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.Collections;
package com.homeadvisor.kafdrop.service;




@Service
public class ConsumerLagService
{
   private final KafkaMonitor kafkaMonitor;

   @Autowired
   public ConsumerLagService(CuratorKafkaMonitor kafkaMonitor)
   {
      this.kafkaMonitor = kafkaMonitor;
   }

   public Collection<ConsumerTopicVO> computeConsumerGroupLag(String groupId, ConsumerLagReportingOffsetType offsetType)
   {
      return computeConsumerGroupLag(groupId, offsetType, null);
   }

   public Collection<ConsumerTopicVO> computeConsumerGroupLag(String groupId, ConsumerLagReportingOffsetType offsetType, String topicId)
   {
// Path: src/main/java/com/homeadvisor/kafdrop/model/ConsumerTopicVO.java
// public class ConsumerTopicVO
// {
//    private final String topic;
//    private final String groupId;
//    private final Map<Integer, ConsumerPartitionVO> offsets = new TreeMap<>();
// 
//    public ConsumerTopicVO(String topic, String groupId)
//    {
//       this.topic = topic;
//       this.groupId = groupId;
//    }
// 
//    public String getTopic()
//    {
//       return topic;
//    }
// 
//    public void addOffset(ConsumerPartitionVO offset)
//    {
//       offsets.put(offset.getPartitionId(), offset);
//    }
// 
//    public long getLag()
//    {
//       return offsets.values().stream()
//          .map(ConsumerPartitionVO::getLag)
//          .filter(lag -> lag >= 0)
//          .reduce(0L, Long::sum);
//    }
// 
//    public long getMaxLag()
//    {
//       return offsets.values().stream()
//          .map(ConsumerPartitionVO::getLag)
//          .filter(lag -> lag >= 0)
//          .reduce(0L, Long::max);
//    }
// 
//    public Collection<ConsumerPartitionVO> getPartitions()
//    {
//       return offsets.values();
//    }
// 
//    public ConsumerPartitionVO getPartition(int partitionId)
//    {
//       return offsets.get(partitionId);
//    }
// 
//    public ConsumerPartitionVO getOrCreatePartition(int partitionId)
//    {
//       return offsets.computeIfAbsent(partitionId, id -> new ConsumerPartitionVO(groupId, topic, id));
//    }
// 
//    public double getCoveragePercent()
//    {
//       return (offsets.size() > 0) ? ((double)getAssignedPartitionCount()) / offsets.size() : 0.0;
//    }
// 
//    public int getAssignedPartitionCount()
//    {
//       return (int) offsets.values().stream()
//          .filter(p -> p.getOwner() != null)
//          .count();
//    }
// 
//    public int getOwnerCount()
//    {
//       return (int)offsets.values().stream()
//          .map(ConsumerPartitionVO::getOwner)
//          .filter(Objects::nonNull)
//          .distinct()
//          .count();
//    }
// }
// 
// Path: src/main/java/com/homeadvisor/kafdrop/model/ConsumerVO.java
// public class ConsumerVO implements Comparable<ConsumerVO>
// {
//    private String groupId;
//    private Map<String, ConsumerTopicVO> topics = new TreeMap<>();
//    private List<ConsumerRegistrationVO> activeInstances = new ArrayList<>();
//    private boolean legacy = false;
// 
//    public ConsumerVO(String groupId)
//    {
//       Validate.notEmpty("groupId is required");
//       this.groupId = groupId;
//    }
// 
//    public boolean isLegacy()
//    {
//       return legacy;
//    }
// 
//    public void setLegacy(boolean legacy)
//    {
//       this.legacy = legacy;
//    }
// 
//    public String getGroupId()
//    {
//       return groupId;
//    }
// 
//    public void setGroupId(String groupId)
//    {
//       this.groupId = groupId;
//    }
// 
//    public void addActiveInstance(ConsumerRegistrationVO id)
//    {
//       activeInstances.add(id);
//    }
// 
//    public List<ConsumerRegistrationVO> getActiveInstances()
//    {
//       return activeInstances;
//    }
// 
//    public List<ConsumerRegistrationVO> getActiveInstancesForTopic(String topic)
//    {
//       return activeInstances.stream()
//          .filter(registration -> registration.subscribesToTopic(topic))
//          .collect(Collectors.toList());
//    }
// 
//    public void addTopic(ConsumerTopicVO topic)
//    {
//       topics.put(topic.getTopic(), topic);
//    }
// 
//    public ConsumerTopicVO getTopic(String topic)
//    {
//       return topics.get(topic);
//    }
// 
//    public ConsumerTopicVO getOrCreateTopic(String topic)
//    {
//       ConsumerTopicVO consumerTopic = getTopic(topic);
//       if (consumerTopic == null)
//       {
//          consumerTopic = new ConsumerTopicVO(topic, groupId);
//          addTopic(consumerTopic);
//       }
//       return consumerTopic;
//    }
// 
//    public Collection<ConsumerTopicVO> getTopics()
//    {
//       return topics.values();
//    }
// 
//    public int getActiveTopicCount()
//    {
//       return topics.values().stream()
//          .map(t -> t.getAssignedPartitionCount() > 0 ? 1 : 0)
//          .reduce(0, Integer::sum);
//    }
// 
//    @Override
//    public int compareTo(ConsumerVO that)
//    {
//       return this.groupId.compareTo(that.groupId);
//    }
// 
//    @Override
//    public boolean equals(Object o)
//    {
//       if (this == o) return true;
//       if (o == null || getClass() != o.getClass()) return false;
// 
//       ConsumerVO vo = (ConsumerVO) o;
// 
//       if (!groupId.equals(vo.groupId)) return false;
// 
//       return true;
//    }
// 
//    @Override
//    public int hashCode()
//    {
//       return groupId.hashCode();
//    }
// 
// }


// Path: src/main/java/com/homeadvisor/kafdrop/service/ConsumerLagService.java
import com.homeadvisor.kafdrop.model.ConsumerTopicVO;
import com.homeadvisor.kafdrop.model.ConsumerVO;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.Collections;

package com.homeadvisor.kafdrop.service;




@Service
public class ConsumerLagService
{
   private final KafkaMonitor kafkaMonitor;

   @Autowired
   public ConsumerLagService(CuratorKafkaMonitor kafkaMonitor)
   {
      this.kafkaMonitor = kafkaMonitor;
   }

   public Collection<ConsumerTopicVO> computeConsumerGroupLag(String groupId, ConsumerLagReportingOffsetType offsetType)
   {
      return computeConsumerGroupLag(groupId, offsetType, null);
   }

   public Collection<ConsumerTopicVO> computeConsumerGroupLag(String groupId, ConsumerLagReportingOffsetType offsetType, String topicId)
   {
      final ConsumerVO consumer = kafkaMonitor