package com.atlassian.bitbucket.mesh.git.ref;

import com.atlassian.bitbucket.mesh.git.AbstractParameters;
import com.atlassian.bitbucket.mesh.repository.Repository;
import com.google.common.collect.ImmutableSet;

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

import static java.lang.Math.max;

public class StreamAnnotatedTagsParameters extends AbstractParameters {

    public static final int UNLIMITED_MESSAGE_LENGTH = -1;

    private final int maxMessageLength;
    private final Repository repository;
    private final Set<String> tagIds;
    private final boolean withMessages;

    private StreamAnnotatedTagsParameters(Builder builder) {
        super(builder);

        //If builder.withMessages is true, normalize the requested length. Otherwise, ignore it. This means the
        //length can either be 0 because it was set that way explicitly, or because withMessages was false
        maxMessageLength = builder.withMessages ? max(UNLIMITED_MESSAGE_LENGTH, builder.maxMessageLength) : 0;
        repository = builder.repository;
        tagIds = builder.tagIds.build();
        withMessages = builder.withMessages && maxMessageLength != 0;
    }

    public int getMaxMessageLength() {
        return maxMessageLength;
    }

    @Nonnull
    public Repository getRepository() {
        return repository;
    }

    @Nonnull
    public Set<String> getTagIds() {
        return tagIds;
    }

    public boolean isWithMessages() {
        return withMessages;
    }

    public static class Builder extends AbstractBuilder<Builder, StreamAnnotatedTagsParameters> {

        private final Repository repository;
        private final ImmutableSet.Builder<String> tagIds;

        private int maxMessageLength;
        private boolean withMessages;

        public Builder(Repository repository) {
            this.repository = repository;

            maxMessageLength = UNLIMITED_MESSAGE_LENGTH;
            tagIds = ImmutableSet.builder();
            withMessages = true;
        }

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

        @Nonnull
        public Builder maxMessageLength(int value) {
            maxMessageLength = value;

            return self();
        }

        @Nonnull
        public Builder tagIds(@Nullable Iterable<String> values) {
            addIf(Objects::nonNull, tagIds, values);

            return self();
        }

        @Nonnull
        public Builder withMessages(boolean value) {
            withMessages = value;

            return self();
        }

        @Nonnull
        @Override
        protected Builder self() {
            return this;
        }
    }
}
