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

import com.atlassian.bitbucket.mesh.git.AbstractParameters;
import com.atlassian.bitbucket.mesh.git.exception.InvalidRefNameException;
import com.atlassian.bitbucket.mesh.repository.Repository;
import com.atlassian.bitbucket.mesh.util.Person;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

import static com.atlassian.bitbucket.mesh.rpc.v1.RpcInvalidRefName.Reason.BLANK;
import static java.util.Objects.requireNonNull;
import static org.apache.commons.lang3.StringUtils.isBlank;
import static org.apache.commons.lang3.StringUtils.trimToNull;

public class AbstractCreateRefParameters extends AbstractParameters {

    private final Person author;
    private final boolean force;
    private final String name;
    private final Repository repository;
    private final String startPoint;

    protected AbstractCreateRefParameters(AbstractCreateBuilder<?, ?> builder) {
        super(builder);

        author = requireNonNull(builder.author, "author");
        force = builder.force;
        name = builder.name;
        repository = builder.repository;
        startPoint = builder.startPoint;
    }

    @Nonnull
    public Person getAuthor() {
        return author;
    }

    @Nonnull
    public String getName() {
        return name;
    }

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

    @Nullable
    public String getStartPoint() {
        return startPoint;
    }

    public boolean isForce() {
        return force;
    }

    public abstract static class AbstractCreateBuilder<B extends AbstractCreateBuilder<B, P>, P extends AbstractCreateRefParameters>
            extends AbstractBuilder<B, P> {

        private final String name;
        private final Repository repository;

        private Person author;
        private boolean force;
        private String startPoint;

        protected AbstractCreateBuilder(@Nonnull Repository repository, @Nonnull String name) {
            this.repository = requireNonNull(repository, "repository");

            if (isBlank(name)) {
                throw new InvalidRefNameException(BLANK, name);
            }
            this.name = name;
        }

        @Nonnull
        public B author(@Nonnull Person value) {
            author = requireNonNull(value, "author");

            return self();
        }

        @Nonnull
        public B force(boolean value) {
            force = value;

            return self();
        }

        @Nonnull
        public B startPoint(@Nullable String value) {
            startPoint = trimToNull(value);

            return self();
        }
    }
}
