package gov.nysenate.openleg.service.spotcheck.agenda;
import com.google.common.collect.Sets;
import gov.nysenate.openleg.dao.agenda.reference.AgendaAlertDao;
import gov.nysenate.openleg.model.agenda.AgendaInfoCommittee;
import gov.nysenate.openleg.model.agenda.CommitteeAgendaAddendumId;
import gov.nysenate.openleg.model.spotcheck.agenda.AgendaAlertInfoCommittee;
import gov.nysenate.openleg.model.spotcheck.ReferenceDataNotFoundEx;
import gov.nysenate.openleg.model.spotcheck.SpotCheckMismatch;
import gov.nysenate.openleg.model.spotcheck.SpotCheckObservation;
import gov.nysenate.openleg.service.spotcheck.base.SpotCheckService;
import org.apache.commons.lang3.NotImplementedException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.Set;
import java.util.TreeSet;
import static gov.nysenate.openleg.model.spotcheck.SpotCheckMismatchType.*;
@Service
public class AgendaSpotCheckService
implements SpotCheckService<CommitteeAgendaAddendumId, AgendaInfoCommittee, AgendaAlertInfoCommittee> {
private static final Logger logger = LoggerFactory.getLogger(AgendaSpotCheckService.class);
@Autowired
AgendaAlertDao agendaAlertDao;
/** {@inheritDoc} */
@Override
public SpotCheckObservation<CommitteeAgendaAddendumId> check(AgendaInfoCommittee content) throws ReferenceDataNotFoundEx {
throw new NotImplementedException(":P");
}
/** {@inheritDoc} */
@Override
public SpotCheckObservation<CommitteeAgendaAddendumId> check(AgendaInfoCommittee content, LocalDateTime start, LocalDateTime end) throws ReferenceDataNotFoundEx {
throw new NotImplementedException(":P");
}
/** {@inheritDoc} */
@Override
public SpotCheckObservation<CommitteeAgendaAddendumId> check(AgendaInfoCommittee content, AgendaAlertInfoCommittee reference) {
final SpotCheckObservation<CommitteeAgendaAddendumId> observation =
new SpotCheckObservation<>(reference.getReferenceId(), content.getId());
checkBills(observation, content, reference);
checkChair(observation, content, reference);
checkMeetingTime(observation, content, reference);
checkLocation(observation, content, reference);
checkNotes(observation, content, reference);
// Some friendly logging
int mismatchCount = observation.getMismatches().size();
if (mismatchCount > 0) {
logger.info("Committee Meeting Agenda {} | {} mismatch(es). | {}", content.getId(), mismatchCount, observation.getMismatchTypes(false));
}
return observation;
}
/** --- Internal Methods --- */
private void checkBills(SpotCheckObservation<CommitteeAgendaAddendumId> obs,
AgendaInfoCommittee content, AgendaAlertInfoCommittee reference) {
Set<String> refBills = new TreeSet<>();
Set<String> contentBills = new TreeSet<>();
reference.getItems().forEach(item -> refBills.add(item.getBillId() + " " + item.getMessage()));
content.getItems().forEach(item -> contentBills.add(item.getBillId() + " " + item.getMessage()));
if (!Sets.symmetricDifference(refBills, contentBills).isEmpty()) {
obs.addMismatch(new SpotCheckMismatch(AGENDA_BILL_LISTING,
StringUtils.join(contentBills, "\n"), StringUtils.join(refBills, "\n")));
}
}
private void checkChair(SpotCheckObservation<CommitteeAgendaAddendumId> obs,
AgendaInfoCommittee content, AgendaAlertInfoCommittee reference) {
String refChair = StringUtils.trim(reference.getChair());
String contentChair = StringUtils.trim(content.getChair());
if (!StringUtils.equals(refChair, contentChair)) {
obs.addMismatch(new SpotCheckMismatch(AGENDA_CHAIR, contentChair, refChair));
}
}
private void checkMeetingTime(SpotCheckObservation<CommitteeAgendaAddendumId> obs,
AgendaInfoCommittee content, AgendaAlertInfoCommittee reference) {
if (content.getMeetingDateTime() == null
|| !content.getMeetingDateTime().equals(reference.getMeetingDateTime())) {
obs.addMismatch(new SpotCheckMismatch(AGENDA_MEETING_TIME,
String.valueOf(content.getMeetingDateTime()), String.valueOf(reference.getMeetingDateTime())));
}
}
private void checkLocation(SpotCheckObservation<CommitteeAgendaAddendumId> obs,
AgendaInfoCommittee content, AgendaAlertInfoCommittee reference) {
String refLocation = StringUtils.trim(reference.getLocation());
String contentLocation = StringUtils.trim(content.getLocation());
if (!StringUtils.equals(refLocation, contentLocation)) {
obs.addMismatch(new SpotCheckMismatch(AGENDA_LOCATION, contentLocation, refLocation));
}
}
private void checkNotes(SpotCheckObservation<CommitteeAgendaAddendumId> obs,
AgendaInfoCommittee content, AgendaAlertInfoCommittee reference) {
String refNotes = StringUtils.trim(reference.getNotes());
String contentNotes = StringUtils.trim(content.getNotes());
if (!StringUtils.equals(refNotes, contentNotes)) {
obs.addMismatch(new SpotCheckMismatch(AGENDA_NOTES, contentNotes, refNotes));
}
}
}