// Path: jashing/src/main/java/com/github/avarabyeu/jashing/core/eventsource/ScheduledEventSource.java
// public abstract class ScheduledEventSource<T extends JashingEvent> extends AbstractScheduledService {
// 
//     private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledEventSource.class);
// 
//     /**
//      * Time period between sending events
//      */
//     @Frequency
//     @Inject
//     private Duration period;
// 
//     /**
//      * ID of event this event source bound to
//      */
//     @EventId
//     @Inject
//     private String eventId;
// 
//     /**
//      * EventBus to send events
//      */
//     @Inject
//     private EventBus eventBus;
// 
// 
//     /**
//      * Executes one iteration of {@link com.google.common.util.concurrent.AbstractScheduledService}
//      * Sends event to event bus
//      *
//      * @throws Exception
//      */
//     @Override
//     protected final void runOneIteration() throws Exception {
//         try {
//             sendEvent(produceEvent());
//         } catch (Exception e){
//             LOGGER.error(MessageFormatter.format("Cannot produce event with id {}", eventId).getMessage(), e);
//         }
// 
//     }
// 
// 
//     protected final void sendEvent(JashingEvent t) {
//         if (null != t) {
//             if (isNull(t.getId())) t.setId(eventId);
//             this.eventBus.post(t);
//         }
//     }
// 
//     @Override
//     protected final Scheduler scheduler() {
//         return AbstractScheduledService.Scheduler.newFixedDelaySchedule(3, period.toMillis(), TimeUnit.MILLISECONDS);
//     }
// 
//     @Override
//     protected final String serviceName() {
//         return "ScheduledEventSource[eventID=" + eventId + "]";
//     }
// 
//     protected abstract T produceEvent();
// }
// 
// Path: jashing/src/main/java/com/github/avarabyeu/jashing/events/ListEvent.java
// public class ListEvent<T> extends JashingEvent {
// 
//     private final List<Item<T>> items;
// 
//     public ListEvent(List<Item<T>> items) {
//         this.items = items;
//     }
// 
//     public List<Item<T>> getItems() {
//         return items;
//     }
// 
//     public static class Item<T> {
//         private String label;
//         private T value;
// 
// 
//         public Item(String label, T value) {
//             this.label = label;
//             this.value = value;
//         }
// 
//         public String getLabel() {
//             return label;
//         }
// 
//         public void setLabel(String label) {
//             this.label = label;
//         }
// 
//         public T getValue() {
//             return value;
//         }
// 
//         public void setValue(T value) {
//             this.value = value;
//         }
//     }
// }


import com.github.avarabyeu.jashing.core.EventSource;
import com.github.avarabyeu.jashing.core.eventsource.ScheduledEventSource;
import com.github.avarabyeu.jashing.events.ListEvent;
import javax.inject.Inject;
import javax.inject.Named;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Comparator;
import java.util.Map;
import java.util.stream.Collectors;
package com.github.avarabyeu.jashing.integration.vcs;



/**
 * Produces top commiters for specified VCS in format [{"commitee" : commitsCount}]
 * <p>
 * Contains <b>required</b> parameter 'logPeriod' - period in days for VCS history search
 *
 * @author Andrey Vorobyov
 */
@EventSource(value = "vcs-top-committers-source", explicitConfiguration = AbstractVcsModule.class)
public class VCSTopCommitersEventSource extends ScheduledEventSource<ListEvent<Long>> {

    private static final Comparator<ListEvent.Item<Long>> ITEM_COMPARATOR = Comparator.comparing(ListEvent.Item::getValue);

    @Inject
    private VCSClient svnClient;

    @Inject
    @Named("forPeriod")
    private Double daysBefore;

    @Override
    protected ListEvent<Long> produceEvent() {
        LocalDateTime fromDateTime = LocalDate.now().minusDays(daysBefore.longValue()).atStartOfDay();
        Map<String, Long> commitsPerUser = svnClient
                .getCommitsPerUser(fromDateTime.atZone(ZoneId.systemDefault()).toInstant());
// Path: jashing/src/main/java/com/github/avarabyeu/jashing/core/eventsource/ScheduledEventSource.java
// public abstract class ScheduledEventSource<T extends JashingEvent> extends AbstractScheduledService {
// 
//     private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledEventSource.class);
// 
//     /**
//      * Time period between sending events
//      */
//     @Frequency
//     @Inject
//     private Duration period;
// 
//     /**
//      * ID of event this event source bound to
//      */
//     @EventId
//     @Inject
//     private String eventId;
// 
//     /**
//      * EventBus to send events
//      */
//     @Inject
//     private EventBus eventBus;
// 
// 
//     /**
//      * Executes one iteration of {@link com.google.common.util.concurrent.AbstractScheduledService}
//      * Sends event to event bus
//      *
//      * @throws Exception
//      */
//     @Override
//     protected final void runOneIteration() throws Exception {
//         try {
//             sendEvent(produceEvent());
//         } catch (Exception e){
//             LOGGER.error(MessageFormatter.format("Cannot produce event with id {}", eventId).getMessage(), e);
//         }
// 
//     }
// 
// 
//     protected final void sendEvent(JashingEvent t) {
//         if (null != t) {
//             if (isNull(t.getId())) t.setId(eventId);
//             this.eventBus.post(t);
//         }
//     }
// 
//     @Override
//     protected final Scheduler scheduler() {
//         return AbstractScheduledService.Scheduler.newFixedDelaySchedule(3, period.toMillis(), TimeUnit.MILLISECONDS);
//     }
// 
//     @Override
//     protected final String serviceName() {
//         return "ScheduledEventSource[eventID=" + eventId + "]";
//     }
// 
//     protected abstract T produceEvent();
// }
// 
// Path: jashing/src/main/java/com/github/avarabyeu/jashing/events/ListEvent.java
// public class ListEvent<T> extends JashingEvent {
// 
//     private final List<Item<T>> items;
// 
//     public ListEvent(List<Item<T>> items) {
//         this.items = items;
//     }
// 
//     public List<Item<T>> getItems() {
//         return items;
//     }
// 
//     public static class Item<T> {
//         private String label;
//         private T value;
// 
// 
//         public Item(String label, T value) {
//             this.label = label;
//             this.value = value;
//         }
// 
//         public String getLabel() {
//             return label;
//         }
// 
//         public void setLabel(String label) {
//             this.label = label;
//         }
// 
//         public T getValue() {
//             return value;
//         }
// 
//         public void setValue(T value) {
//             this.value = value;
//         }
//     }
// }


// Path: extensions/jashing-cvs/src/main/java/com/github/avarabyeu/jashing/integration/vcs/VCSTopCommitersEventSource.java
import com.github.avarabyeu.jashing.core.EventSource;
import com.github.avarabyeu.jashing.core.eventsource.ScheduledEventSource;
import com.github.avarabyeu.jashing.events.ListEvent;
import javax.inject.Inject;
import javax.inject.Named;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Comparator;
import java.util.Map;
import java.util.stream.Collectors;

package com.github.avarabyeu.jashing.integration.vcs;



/**
 * Produces top commiters for specified VCS in format [{"commitee" : commitsCount}]
 * <p>
 * Contains <b>required</b> parameter 'logPeriod' - period in days for VCS history search
 *
 * @author Andrey Vorobyov
 */
@EventSource(value = "vcs-top-committers-source", explicitConfiguration = AbstractVcsModule.class)
public class VCSTopCommitersEventSource extends ScheduledEventSource<ListEvent<Long>> {

    private static final Comparator<ListEvent.Item<Long>> ITEM_COMPARATOR = Comparator.comparing(ListEvent.Item::getValue);

    @Inject
    private VCSClient svnClient;

    @Inject
    @Named("forPeriod")
    private Double daysBefore;

    @Override
    protected ListEvent<Long> produceEvent() {
        LocalDateTime fromDateTime = LocalDate.now().minusDays(daysBefore.longValue()).atStartOfDay();
        Map<String, Long> commitsPerUser = svnClient
                .getCommitsPerUser(fromDateTime.atZone(ZoneId.systemDefault()).toInstant());
        return new ListEvent<>(commitsPerUser.entrySet()