package com.atlassian.bitbucket.internal.mirroring.mirror.sync;

import com.atlassian.bitbucket.repository.MinimalRef;
import com.atlassian.bitbucket.repository.RefChange;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.scm.mirror.MirrorSyncCallback;
import com.google.common.collect.ImmutableList;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import java.io.IOException;
import java.util.Collection;
import java.util.List;

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

public class MirrorRefChangeCallback implements MirrorSyncCallback {

    private static final Logger log = LoggerFactory.getLogger(MirrorRefChangeCallback.class);

    private final ImmutableList.Builder<RefChange> changes;
    private final ImmutableList.Builder<MinimalRef> failedRefs;
    private final Repository repository;
    private int count;

    public MirrorRefChangeCallback(@Nonnull Repository repository) {
        this.repository = checkNotNull(repository, "repository");

        changes = ImmutableList.builder();
        failedRefs = ImmutableList.builder();
    }

    @Nonnull
    public List<RefChange> getChanges() {
        return changes.build();
    }

    public int getCount() {
        return count;
    }

    @Nonnull
    public Collection<MinimalRef> getFailedRefs() {
        return failedRefs.build();
    }

    @Override
    public boolean onFailedRef(@Nonnull MinimalRef ref) throws IOException {
        failedRefs.add(ref);

        return true;
    }

    @Override
    public boolean onRefChange(@Nonnull RefChange refChange) throws IOException {
        ++count;
        changes.add(refChange);
        if (log.isDebugEnabled()) {
            log.debug("{}: synced {} ({})", repository, refChange.getRef().getId(),
                    StringUtils.lowerCase(refChange.getType().name()));
        }
        return true;
    }
}
