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

import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.user.ApplicationUser;
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 for creating or updating a {@link RefRestriction}.
 * These requests are handled by the {@link RefRestrictionService}.
 * The {@link Builder} should be used to construct these requests.
 */
public class SetRestrictionRequest {

    private final List<String> groupGrants;
    private final List<ApplicationUser> userGrants;
    private final Repository repository;
    private final RefMatcher matcher;
    private final RefRestrictionType type;

    private SetRestrictionRequest(Builder builder) {
        groupGrants = builder.groupGrants.build();
        repository = requireNonNull(builder.repository, "repositoryId");
        matcher = requireNonNull(builder.matcher, "matcher");
        type = requireNonNull(builder.type, "type");
        userGrants = builder.userGrants.build();
    }

    @Nonnull
    public List<String> getGroupGrants() {
        return groupGrants;
    }

    public Repository getRepository() {
        return repository;
    }

    public int getRepositoryId() {
        return repository.getId();
    }

    @Nonnull
    public RefMatcher getMatcher() {
        return matcher;
    }

    @Nonnull
    public RefRestrictionType getType() {
        return type;
    }

    @Nonnull
    public List<ApplicationUser> getUserGrants() {
        return userGrants;
    }

    public static class Builder extends BuilderSupport {

        private final ImmutableList.Builder<String> groupGrants = ImmutableList.builder();
        private final ImmutableList.Builder<ApplicationUser> userGrants = ImmutableList.builder();

        private Repository repository;
        private RefMatcher matcher;
        private RefRestrictionType type;

        public Builder(Repository repository, RefMatcher matcher, RefRestrictionType type) {
            this.repository = repository;
            this.matcher = matcher;
            this.type = type;
        }

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

        @Nonnull
        public Builder grantGroups(@Nonnull Iterable<String> value) {
            groupGrants.addAll(requireNonNull(value, "groupGrants"));
            return this;
        }

        @Nonnull
        public Builder grantUsers(@Nonnull Iterable<ApplicationUser> value) {
            userGrants.addAll(requireNonNull(value, "userGrants"));
            return this;
        }
    }
}
