package com.atlassian.stash.internal.pull;

import com.atlassian.bitbucket.pull.PullRequestOrder;
import com.atlassian.bitbucket.pull.PullRequestState;
import com.atlassian.bitbucket.util.BuilderSupport;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Objects;
import java.util.Set;

public class PullRequestSearchCriteria {

    private final Set<String> fromRefIds;
    private final Integer fromRepositoryId;
    private final PullRequestOrder order;
    private final Iterable<PullRequestParticipantCriteria> participants;
    private final PullRequestState state;
    private final Set<String> toRefIds;
    private final Integer toRepositoryId;

    private PullRequestSearchCriteria(Builder builder) {
        fromRefIds = builder.fromRefIds.build();
        fromRepositoryId = builder.fromRepositoryId;
        order = builder.order;
        participants = builder.participants.build();
        state = builder.state;
        toRefIds = builder.toRefIds.build();
        toRepositoryId = builder.toRepositoryId;
    }

    public Collection<String> getFromRefIds() {
        return fromRefIds;
    }

    public Integer getFromRepositoryId() {
        return fromRepositoryId;
    }

    public PullRequestOrder getOrder() {
        return order;
    }

    public Iterable<PullRequestParticipantCriteria> getParticipants() {
        return participants;
    }

    public PullRequestState getState() {
        return state;
    }

    public Collection<String> getToRefIds() {
        return toRefIds;
    }

    public Integer getToRepositoryId() {
        return toRepositoryId;
    }

    public static class Builder extends BuilderSupport {

        private final ImmutableSet.Builder<String> fromRefIds;
        private final ImmutableList.Builder<PullRequestParticipantCriteria> participants;
        private final ImmutableSet.Builder<String> toRefIds;

        private Integer fromRepositoryId;
        private PullRequestOrder order;
        private PullRequestState state;
        private Integer toRepositoryId;

        public Builder() {
            fromRefIds = ImmutableSet.builder();
            participants = ImmutableList.builder();
            toRefIds = ImmutableSet.builder();
        }

        @Nonnull
        public PullRequestSearchCriteria build() {
            return new PullRequestSearchCriteria(this);
        }

        @Nonnull
        public Builder fromRefIds(@Nullable Iterable<String> values) {
            addIf(Objects::nonNull, fromRefIds, values);
            return this;
        }

        @Nonnull
        public Builder fromRepositoryId(@Nullable Integer value) {
            fromRepositoryId = value;
            return this;
        }

        @Nonnull
        public Builder order(@Nullable PullRequestOrder value) {
            order = value;
            return this;
        }

        @Nonnull
        public Builder participant(@Nullable PullRequestParticipantCriteria value) {
            addIf(Objects::nonNull, participants, value);
            return this;
        }

        @Nonnull
        public Builder participants(@Nullable Iterable<PullRequestParticipantCriteria> values) {
            addIf(Objects::nonNull, participants, values);
            return this;
        }

        @Nonnull
        public Builder state(@Nullable PullRequestState value) {
            state = value;
            return this;
        }

        @Nonnull
        public Builder toRefIds(@Nullable Iterable<String> values) {
            addIf(Objects::nonNull, toRefIds, values);
            return this;
        }

        @Nonnull
        public Builder toRepositoryId(@Nullable Integer value) {
            toRepositoryId = value;
            return this;
        }
    }
}
