package com.atlassian.bitbucket.mesh.repository;

import com.atlassian.bitbucket.mesh.util.BuilderSupport;
import com.google.common.collect.ImmutableSet;

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

import static java.util.Objects.requireNonNull;

public class DeleteRepositoryParameters {

    public static final Duration DEFAULT_LOCK_TIMEOUT = Duration.ofSeconds(30L);

    private final Set<Repository> forks;
    private final Duration lockTimeout;
    private final boolean onlyForkOfOrigin;
    private final boolean onlyMember;
    private final Repository origin;
    private final Repository repository;

    private DeleteRepositoryParameters(Builder builder) {
        forks = builder.forks.build();
        lockTimeout = builder.lockTimeout;
        onlyForkOfOrigin = builder.onlyForkOfOrigin;
        onlyMember = builder.onlyMember;
        origin = builder.origin;
        repository = builder.repository;
    }

    @Nonnull
    public Set<Repository> getForks() {
        return forks;
    }

    @Nonnull
    public Duration getLockTimeout() {
        return lockTimeout;
    }

    @Nullable
    public Repository getOrigin() {
        return origin;
    }

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

    public boolean isOnlyForkOfOrigin() {
        return onlyForkOfOrigin;
    }

    public boolean isOnlyMember() {
        return onlyMember;
    }

    public static class Builder extends BuilderSupport {

        private final ImmutableSet.Builder<Repository> forks;
        private final Repository repository;

        private Duration lockTimeout;
        private boolean onlyForkOfOrigin;
        private boolean onlyMember;
        private Repository origin;

        public Builder(@Nonnull Repository repository) {
            this.repository = requireNonNull(repository, "repository");
            forks = ImmutableSet.builder();
            lockTimeout = DEFAULT_LOCK_TIMEOUT;
        }

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

        @Nonnull
        public Builder forks(@Nullable Repository value, @Nullable Repository... moreValues) {
            addIf(Objects::nonNull, forks, value, moreValues);
            return this;
        }

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

        @Nonnull
        public Builder lockTimeout(@Nonnull Duration value) {
            lockTimeout = requireNonNull(value, "lockTimeout");
            return this;
        }

        @Nonnull
        public Builder onlyForkOfOrigin(boolean value) {
            onlyForkOfOrigin = value;
            return this;
        }
        
        @Nonnull
        public Builder onlyMember(boolean value) {
            onlyMember = value;
            return this;
        }

        @Nonnull
        public Builder origin(@Nullable Repository value) {
            origin = value;
            return this;
        }
    }
}
