package com.atlassian.bitbucket.user;

import com.atlassian.bitbucket.util.BuilderSupport;
import org.apache.commons.lang3.StringUtils;

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

public abstract class AbstractServiceUserRequest {

    private final boolean active;
    private final String displayName;
    private final String emailAddress;
    private final String label;
    private final String name;

    protected AbstractServiceUserRequest(AbstractBuilder builder) {
        active = builder.active;
        displayName = builder.displayName;
        emailAddress = builder.emailAddress;
        label = builder.label;
        name = builder.name;
    }

    /**
     * @return an optional display name. If not set, the display name will default to the {@link #getName username}
     */
    @Nullable
    public String getDisplayName() {
        return displayName;
    }

    /**
     * @return an optional email address
     */
    @Nullable
    public String getEmailAddress() {
        return emailAddress;
    }

    /**
     * @return an optional label. If not set, the label will default to the {@link ServiceUser#DEFAULT_LABEL}
     */
    @Nullable
    public String getLabel() {
        return label;
    }

    /**
     * @return an optional name. If not set, a username will be generated.
     */
    @Nullable
    public String getName() {
        return name;
    }

    /**
     * @return whether the user should be active
     */
    public boolean isActive() {
        return active;
    }

    protected abstract static class AbstractBuilder<B extends AbstractBuilder<B>> extends BuilderSupport {
        private boolean active;
        private String displayName;
        private String emailAddress;
        private String label;
        private String name;

        protected AbstractBuilder() {
            active = true;
        }

        protected AbstractBuilder(@Nonnull ServiceUser user) {
            active = user.isActive();
            label = user.getLabel();
            displayName = user.getDisplayName();
            name = user.getName();
        }

        /**
         * @param value whether the service user should be active
         * @return {@code this}
         */
        @Nonnull
        public B active(boolean value) {
            active = value;
            return self();
        }

        /**
         * @param value the display name to set
         * @return {@code this}
         */
        @Nonnull
        public B displayName(@Nullable String value) {
            displayName = value;
            return self();
        }

        /**
         * @param value the email address to set
         * @return {@code this}
         */
        @Nonnull
        public B emailAddress(@Nullable String value) {
            emailAddress = value;
            return self();
        }

        /**
         * @param value the label to set
         * @return {@code this}
         */
        @Nonnull
        public B label(@Nullable String value) {
            label = StringUtils.trimToNull(value);
            return self();
        }

        /**
         * @param value the username to set
         * @return {@code this}
         */
        @Nonnull
        public B name(@Nullable String value) {
            name = value;
            return self();
        }

        protected abstract B self();
    }
}
