package com.atlassian.stash.internal.pull.rescope;

import com.atlassian.bitbucket.pull.RescopeDetails;

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

import static java.util.Objects.requireNonNull;

/**
 * Represents a {@link com.atlassian.bitbucket.scm.pull.PullRequestRescope} resulting in the associated pull request
 * being updated (and kept open).
 *
 * @since 4.5
 */
public class UpdateOutcome implements RescopeOutcome {

    private final RescopeDetails addedCommits;
    private final RescopeDetails removedCommits;

    public UpdateOutcome(@Nonnull RescopeDetails addedCommits, @Nonnull RescopeDetails removedCommits) {
        this.addedCommits = requireNonNull(addedCommits, "addedCommits");
        this.removedCommits = requireNonNull(removedCommits, "removedCommits");
    }

    @Override
    public <T> T accept(@Nonnull RescopeOutcomeVisitor<T> visitor) {
        return visitor.visit(this);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }
        UpdateOutcome that = (UpdateOutcome) o;
        return Objects.equals(addedCommits, that.addedCommits) &&
                Objects.equals(removedCommits, that.removedCommits);
    }

    /**
     * @return details about what commits, if any were added to the scope of the pull request. The
     *         {@link RescopeDetails#getCommits() commits list} is limited for performance reasons. Use
     *         {@link RescopeDetails#getTotal()} ()} to determine the total number of commits that were added to the
     *         scope of the pull request. If more commits were added to the scope than are returned in this list, the
     *         list will contain the most recent commits that were added. Returns {@code null} if the scope change
     *         hasn't been determined.
     */
    @Nonnull
    public RescopeDetails getAddedCommits() {
        return addedCommits;
    }

    /**
     * @return details about what commits, if any were removed from the scope of the pull request. The
     *         {@link RescopeDetails#getCommits() commits list} is limited for performance reasons. Use
     *         {@link RescopeDetails#getTotal()} ()} to determine the total number of commits that were removed from the
     *         scope of the pull request. If more commits were removed from the scope than are returned in this list,
     *         the list will contain the most recent commits that were removed. Returns {@code null} if the scope change
     *         hasn't been determined.
     */
    @Nonnull
    public RescopeDetails getRemovedCommits() {
        return removedCommits;
    }

    @Override
    public int hashCode() {
        return Objects.hash(addedCommits, removedCommits);
    }

    @Override
    public String toString() {
        return "{UpdateOutcome added: " + addedCommits + ", removed: " + removedCommits + "}";
    }
}
