// Path: src/main/java/com/bazoud/elasticsearch/river/git/beans/Context.java
// @Data
// @SuppressWarnings("PMD.UnusedPrivateField")
// public class Context {
//     private String name;
//     private String uri;
//     private File projectPath;
//     private Repository repository;
//     private String workingDir =
//         System.getProperty("user.home") + File.separator + ".elasticsearch-river-git";
//     private Collection<Ref> refs;
//     private Client client;
//     private Optional<Pattern> issuePattern = Optional.absent();
//     private String issueRegex;
//     private boolean indexingDiff;
//     private long updateRate = TimeUnit.MILLISECONDS.convert(15, TimeUnit.MINUTES);
//     private String type = "git";
//     private String riverName;
//     private String riverIndexName;
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/flow/functions/TrackingRefUpdateToRef.java
// public class TrackingRefUpdateToRef extends MyFunction<TrackingRefUpdate, Ref> {
//     private Repository repository;
// 
//     public TrackingRefUpdateToRef(Repository repository) {
//         this.repository = repository;
//     }
// 
//     @Override
//     public Ref doApply(TrackingRefUpdate input) throws Throwable {
//         return repository.getRef(input.getLocalName());
//     }
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/guava/MyFunction.java
// public abstract class MyFunction<F, T> implements Function<F, T> {
//     private static ESLogger logger = Loggers.getLogger(MyFunction.class);
// 
//     @Override
//     public T apply(F input) {
//         T output = null;
//         try {
//             output = doApply(input);
//         } catch (Throwable e) {
//             logger.error(this.getClass().getName(), e);
//             Throwables.propagate(e);
//         }
//         return output;
//     }
// 
//     public abstract T doApply(F input) throws Throwable;
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/jgit/LoggingProgressMonitor.java
// public class LoggingProgressMonitor implements ProgressMonitor {
//     private ESLogger logger;
// 
//     public LoggingProgressMonitor(ESLogger logger) {
//         this.logger = logger;
//     }
// 
//     @Override
//     public void start(int totalTasks) {
//     }
// 
//     @Override
//     public void beginTask(String title, int totalWork) {
//         logger.info(title);
//     }
// 
//     @Override
//     public void update(int completed) {
//     }
// 
//     @Override
//     public void endTask() {
//     }
// 
//     @Override
//     public boolean isCancelled() {
//         return false;
//     }
// }


import java.util.Collection;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.TrackingRefUpdate;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import com.bazoud.elasticsearch.river.git.beans.Context;
import com.bazoud.elasticsearch.river.git.flow.functions.TrackingRefUpdateToRef;
import com.bazoud.elasticsearch.river.git.guava.MyFunction;
import com.bazoud.elasticsearch.river.git.jgit.LoggingProgressMonitor;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
import static org.eclipse.jgit.lib.RefUpdate.Result.NO_CHANGE;
package com.bazoud.elasticsearch.river.git.flow;





/**
 * @author Olivier Bazoud
 */
public class FetchRepositoryFunction extends MyFunction<Context, Context> {
    private static ESLogger logger = Loggers.getLogger(FetchRepositoryFunction.class);

    @Override
    public Context doApply(Context context) throws Throwable {
        final Repository repository = new FileRepositoryBuilder()
            .setGitDir(context.getProjectPath())
                // scan environment GIT_* variables
            .readEnvironment()
            .findGitDir()
            .setMustExist(true)
            .build();
        context.setRepository(repository);

        logger.info("Fetching '{}' repository at path: '{}'", context.getName(), context.getProjectPath());

        Git git = new Git(repository);

        FetchResult fetchResult = git.fetch()
            .setProgressMonitor(new LoggingProgressMonitor(logger))
            .call();

        Collection<Ref> refs = FluentIterable
            .from(fetchResult.getTrackingRefUpdates())
            .filter(Predicates.not(new Predicate<TrackingRefUpdate>() {
                @Override
                public boolean apply(TrackingRefUpdate input) {
                    return NO_CHANGE.equals(input.getResult());
                }
            }))
// Path: src/main/java/com/bazoud/elasticsearch/river/git/beans/Context.java
// @Data
// @SuppressWarnings("PMD.UnusedPrivateField")
// public class Context {
//     private String name;
//     private String uri;
//     private File projectPath;
//     private Repository repository;
//     private String workingDir =
//         System.getProperty("user.home") + File.separator + ".elasticsearch-river-git";
//     private Collection<Ref> refs;
//     private Client client;
//     private Optional<Pattern> issuePattern = Optional.absent();
//     private String issueRegex;
//     private boolean indexingDiff;
//     private long updateRate = TimeUnit.MILLISECONDS.convert(15, TimeUnit.MINUTES);
//     private String type = "git";
//     private String riverName;
//     private String riverIndexName;
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/flow/functions/TrackingRefUpdateToRef.java
// public class TrackingRefUpdateToRef extends MyFunction<TrackingRefUpdate, Ref> {
//     private Repository repository;
// 
//     public TrackingRefUpdateToRef(Repository repository) {
//         this.repository = repository;
//     }
// 
//     @Override
//     public Ref doApply(TrackingRefUpdate input) throws Throwable {
//         return repository.getRef(input.getLocalName());
//     }
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/guava/MyFunction.java
// public abstract class MyFunction<F, T> implements Function<F, T> {
//     private static ESLogger logger = Loggers.getLogger(MyFunction.class);
// 
//     @Override
//     public T apply(F input) {
//         T output = null;
//         try {
//             output = doApply(input);
//         } catch (Throwable e) {
//             logger.error(this.getClass().getName(), e);
//             Throwables.propagate(e);
//         }
//         return output;
//     }
// 
//     public abstract T doApply(F input) throws Throwable;
// }
// 
// Path: src/main/java/com/bazoud/elasticsearch/river/git/jgit/LoggingProgressMonitor.java
// public class LoggingProgressMonitor implements ProgressMonitor {
//     private ESLogger logger;
// 
//     public LoggingProgressMonitor(ESLogger logger) {
//         this.logger = logger;
//     }
// 
//     @Override
//     public void start(int totalTasks) {
//     }
// 
//     @Override
//     public void beginTask(String title, int totalWork) {
//         logger.info(title);
//     }
// 
//     @Override
//     public void update(int completed) {
//     }
// 
//     @Override
//     public void endTask() {
//     }
// 
//     @Override
//     public boolean isCancelled() {
//         return false;
//     }
// }


// Path: src/main/java/com/bazoud/elasticsearch/river/git/flow/FetchRepositoryFunction.java
import java.util.Collection;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.eclipse.jgit.transport.FetchResult;
import org.eclipse.jgit.transport.TrackingRefUpdate;
import org.elasticsearch.common.logging.ESLogger;
import org.elasticsearch.common.logging.Loggers;
import com.bazoud.elasticsearch.river.git.beans.Context;
import com.bazoud.elasticsearch.river.git.flow.functions.TrackingRefUpdateToRef;
import com.bazoud.elasticsearch.river.git.guava.MyFunction;
import com.bazoud.elasticsearch.river.git.jgit.LoggingProgressMonitor;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
import static org.eclipse.jgit.lib.RefUpdate.Result.NO_CHANGE;

package com.bazoud.elasticsearch.river.git.flow;





/**
 * @author Olivier Bazoud
 */
public class FetchRepositoryFunction extends MyFunction<Context, Context> {
    private static ESLogger logger = Loggers.getLogger(FetchRepositoryFunction.class);

    @Override
    public Context doApply(Context context) throws Throwable {
        final Repository repository = new FileRepositoryBuilder()
            .setGitDir(context.getProjectPath())
                // scan environment GIT_* variables
            .readEnvironment()
            .findGitDir()
            .setMustExist(true)
            .build();
        context.setRepository(repository);

        logger.info("Fetching '{}' repository at path: '{}'", context.getName(), context.getProjectPath());

        Git git = new Git(repository);

        FetchResult fetchResult = git.fetch()
            .setProgressMonitor(new LoggingProgressMonitor(logger))
            .call();

        Collection<Ref> refs = FluentIterable
            .from(fetchResult.getTrackingRefUpdates())
            .filter(Predicates.not(new Predicate<TrackingRefUpdate>() {
                @Override
                public boolean apply(TrackingRefUpdate input) {
                    return NO_CHANGE.equals(input.getResult());
                }
            }))
            .transform(new TrackingRefUpdateToRef(repository))