package com.atlassian.bitbucket.repository.ref.restriction;

import com.atlassian.bitbucket.repository.MinimalRef;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.util.BuilderSupport;
import com.google.common.collect.ImmutableList;

import javax.annotation.Nonnull;
import java.util.List;

import static java.util.Objects.requireNonNull;

/**
 * A request to pass to {@link RefRestrictionService#hasPermission hasPermission}.
 * Specifies which type of access should be checked and for which {@link MinimalRef refs}.
 */
public class RefAccessRequest {

    private final RefAccessType accessType;
    private final List<MinimalRef> refs;
    private final Repository repository;

    RefAccessRequest(Builder builder) {
        accessType = builder.accessType;
        refs = builder.refs.build();
        repository = builder.repository;
    }

    @Nonnull
    public RefAccessType getAccessType() {
        return accessType;
    }

    @Nonnull
    public List<MinimalRef> getRefs() {
        return refs;
    }

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

    public static class Builder extends BuilderSupport {

        private final RefAccessType accessType;
        private final ImmutableList.Builder<MinimalRef> refs;
        private final Repository repository;

        public Builder(@Nonnull Repository repository, @Nonnull RefAccessType accessType) {
            this.accessType = requireNonNull(accessType, "accessType");
            this.repository = requireNonNull(repository, "repository");
            refs = ImmutableList.builder();
        }

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

        @Nonnull
        public Builder ref(@Nonnull MinimalRef value) {
            refs.add(requireNonNull(value, "ref"));

            return this;
        }

        @Nonnull
        public Builder refs(@Nonnull Iterable<MinimalRef> value) {
            refs.addAll(requireNonNull(value, "ref"));

            return this;
        }
    }
}
