package com.atlassian.bitbucket.mesh.transaction;

import com.atlassian.bitbucket.mesh.git.binary.GitBinary;
import com.atlassian.bitbucket.mesh.git.ref.Branch;
import com.atlassian.bitbucket.mesh.rpc.v1.RpcProposedRefUpdate;
import com.atlassian.bitbucket.mesh.rpc.v1.RpcTransaction;
import com.atlassian.bitbucket.mesh.rpc.v1.RpcUpdateRefsRequest;
import com.atlassian.bitbucket.mesh.util.ShaUtils;
import com.google.protobuf.ByteString;

import javax.annotation.Resource;

public class TransactUpdateRefsTest extends AbstractPreparedActionWriteTest {

    @Resource
    private GitBinary gitBinary;

    @Override
    protected RpcTransaction.Builder createTransaction(RpcTransaction.Builder builder) {
        return builder.setUpdateRefs(RpcUpdateRefsRequest.newBuilder()
                .addRefUpdates(RpcProposedRefUpdate.newBuilder()
                        .setOldHash(ShaUtils.NULL_SHA1)
                        .setNewHash("53979b3304bece75a3852a3d250dbaed64d45430")
                        .setRefId(ByteString.copyFromUtf8("refs/heads/new-branch")))
                .setRepository(repository.getId()));
    }

    @Override
    protected RpcTransaction.Builder createTransactionThatTriggersError(RpcTransaction.Builder builder) {
        return builder.setUpdateRefs(RpcUpdateRefsRequest.newBuilder()
                .addRefUpdates(RpcProposedRefUpdate.newBuilder()
                        .setOldHash("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa") //does not exist
                        .setNewHash("53979b3304bece75a3852a3d250dbaed64d45430")
                        .setRefId(ByteString.copyFromUtf8("refs/heads/cannot-create-branch")))
                .setRepository(repository.getId()));
    }

    @Override
    protected boolean isApplied(RpcTransaction transaction) {
        for (RpcProposedRefUpdate updateRef : transaction.getUpdateRefs().getRefUpdatesList()) {
            Branch branch = agent.resolveBranch(repository, updateRef.getRefId().toStringUtf8(), true);
            if (branch == null && !ShaUtils.isNull(updateRef.getNewHash())) {
                //Branch was not resolved, but should have been created or updated
                return false;
            }
            if (branch != null && !ShaUtils.hashesMatch(branch.getLatestCommit(), updateRef.getNewHash())) {
                //Branch was resolved, but does not match the expected hash
                return false;
            }
        }
        return true;
    }
}
