package com.atlassian.stash.internal.repository.sync.command;

import com.atlassian.stash.internal.repository.sync.RefSyncConfig;
import com.atlassian.bitbucket.repository.RefChange;
import com.atlassian.bitbucket.repository.RefChangeType;
import com.atlassian.bitbucket.repository.sync.RejectedRefState;
import com.atlassian.bitbucket.scm.git.GitAgent;
import com.atlassian.bitbucket.scm.git.command.GitCommandBuilderFactory;

/**
 * @since 2.6
 */
public class ReviewRefsCommand extends AbstractSynchronizeRefsCommand<ReviewRefsCommandParameters> {

    public ReviewRefsCommand(GitAgent agent, GitCommandBuilderFactory builderFactory, RefSyncConfig config,
                             ReviewRefsCommandParameters parameters) {
        super(agent, builderFactory, config, parameters);
    }

    @Override
    protected boolean synchronize() {
        for (RefChange change : parameters) {
            RejectedRefState state = calculateState(change);
            if (state == null) {
                addChangedRef(change);
            } else {
                addRejectedRef(change.getRef().getId(), state);
            }
        }

        return false;
    }

    private RejectedRefState calculateState(RefChange change) {
        RefChangeType changeType = change.getType();
        if (changeType == RefChangeType.DELETE) {
            //Deletions are always "in sync" under review. If the ref still exists upstream, it will be recreated
            //if new changes are pushed to it there
            return null;
        }

        //Since we have the RefChange, which includes the commit ID, there's no need to resolve that ref.
        //This method will just resolve the upstream ref, and use the provided hash for the local one
        return calculateState(change.getRef().getId(), change.getToHash());
    }
}
