package com.atlassian.bitbucket.util;

import com.atlassian.bitbucket.scm.CommandResult;

import javax.annotation.Nonnull;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * A base class for building summary objects that can be provided to callbacks when operations complete. This base
 * class provides a {@link CommandResult result}, indicating whether the operation succeeded, failed or was canceled.
 */
public abstract class AbstractSummary {

    private final CommandResult result;

    protected AbstractSummary(AbstractBuilder<?, ?> builder) {
        result = builder.result;
    }

    /**
     * Retrieves the {@link CommandResult result} of the operation.
     *
     * @return the operation result
     */
    @Nonnull
    public CommandResult getResult() {
        return result;
    }

    public abstract static class AbstractBuilder<B extends AbstractBuilder<B, S>, S extends AbstractSummary>
            extends BuilderSupport {

        private final CommandResult result;

        /**
         * Creates and initializes a new builder using details from the provided {@link AbstractSummary summary}.
         *
         * @param summary the summary to initialize this builder from
         */
        protected AbstractBuilder(@Nonnull AbstractSummary summary) {
            this(checkNotNull(summary, "summary").getResult());
        }

        /**
         * Creates a new builder with the provided {@link CommandResult result}.
         *
         * @param result the operation result for the summary
         */
        protected AbstractBuilder(@Nonnull CommandResult result) {
            this.result = checkNotNull(result, "result");
        }

        @Nonnull
        public abstract S build();

        @Nonnull
        protected abstract B self();
    }
}
