package com.atlassian.bitbucket.mesh.git.builder.revlist;

import com.atlassian.bitbucket.mesh.git.GitProcessCompletionHandler;
import com.atlassian.bitbucket.mesh.git.exception.CommitNotFoundException;
import com.atlassian.bitbucket.mesh.process.ProcessSummary;
import com.google.common.collect.Iterables;

import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.Set;
import java.util.stream.Stream;

import static com.atlassian.bitbucket.mesh.util.MoreCollectors.toImmutableSet;
import static java.util.Objects.requireNonNull;
import static org.apache.commons.lang3.StringUtils.isNotBlank;

public class RevCoreCompletionHandler extends GitProcessCompletionHandler {

    private final boolean ignoreMissing;
    private final Set<String> revs;

    public RevCoreCompletionHandler(Collection<String> revs, boolean ignoreMissing) {
        this(revs.stream(), ignoreMissing);
    }

    public RevCoreCompletionHandler(Collection<String> excludes, Collection<String> includes,
                                    boolean ignoreMissing) {
        this(Stream.concat(includes.stream().limit(3), excludes.stream().limit(3)),
                ignoreMissing);
    }

    public RevCoreCompletionHandler(Stream<String> revs, boolean ignoreMissing) {
        this.revs = revs.limit(6).collect(toImmutableSet());
        this.ignoreMissing = ignoreMissing;
    }

    @Override
    protected void onError(@Nonnull ProcessSummary summary) {
        boolean hasStderr = isNotBlank(summary.getStderr());
        if (hasStderr && summary.getStderr().startsWith(USAGE)) {
            if (ignoreMissing) {
                //This will also ignore any non-zero exit code or thrown exception, which is why this
                //class overrides onError instead of evaluateStdErr
                return;
            }
            if (!revs.isEmpty()) {
                throw new CommitNotFoundException(requireNonNull(Iterables.getFirst(revs, null), "revs[0]"));
            }
        }

        super.onError(summary);
    }
}
