package com.atlassian.bitbucket.mesh.git;

import com.atlassian.bitbucket.mesh.git.commit.Commit;
import com.atlassian.bitbucket.mesh.git.commit.CommitCallback;
import com.atlassian.bitbucket.mesh.git.content.MinimalChange;
import com.atlassian.bitbucket.mesh.rpc.v1.RpcGetPullRequestCommitsResponseFragment;
import io.grpc.stub.StreamObserver;

import javax.annotation.Nonnull;

class ObserverPullRequestCommitCallback
        extends AbstractObserverCallback<RpcGetPullRequestCommitsResponseFragment>
        implements CommitCallback {

    private final RpcGetPullRequestCommitsResponseFragment.Builder fragment;

    ObserverPullRequestCommitCallback(StreamObserver<RpcGetPullRequestCommitsResponseFragment> observer) {
        super(observer);

        fragment = RpcGetPullRequestCommitsResponseFragment.newBuilder();
    }

    @Override
    public boolean onCommit(@Nonnull Commit commit, MinimalChange renameChange) {
        fragment.addCommits(commit.toCommit());
        if (fragment.getCommitsCount() >= FRAGMENT_SIZE) {
            sendFragment();
        }

        return !isCanceled();
    }

    void onEnd() {
        sendLastFragment();
        observer.onCompleted();
    }

    private void sendFragment() {
        observer.onNext(fragment.build());
        fragment.clearCommits();
    }

    private void sendLastFragment() {
        if (fragment.getCommitsCount() > 0) {
            sendFragment();
        }
    }
}
