package com.atlassian.stash.internal.commit.graph.cache;

import com.atlassian.bitbucket.ServerException;
import com.atlassian.bitbucket.i18n.I18nService;
import com.atlassian.util.contentcache.ContentProvider;

import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.scm.ScmService;
import com.google.common.base.Throwables;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;

import static com.atlassian.stash.internal.commit.graph.cache.CachedCommitGraphOutputStream.CachedCommitGraphOutputStreamIOException;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Traverses the commit graph using the native scm.
 *
 * @since 2.11
 */
public class TraversalScmContentProvider implements ContentProvider {

    private final ScmService scmService;
    private final Repository repository;
    private final I18nService i18nService;

    public TraversalScmContentProvider(ScmService scmService, Repository repository, I18nService i18nService) {
        checkNotNull(scmService, "scmService");
        checkNotNull(repository, "repository");
        checkNotNull(i18nService, "i18nService");

        this.scmService = scmService;
        this.repository = repository;
        this.i18nService = i18nService;
    }

    @Override
    public void apply(OutputStream out) throws IOException {
        try {
            scmService.getCommandFactory(repository).traverseCommits(new PersistingTraversalCallback(out, i18nService)).call();
        } catch (ServerException e) {
            // hide ServerExceptions from the SCM layer since these are just noise
            Throwables.propagateIfInstanceOf(e.getCause(), CachedCommitGraphOutputStreamIOException.class);
            throw e;
        }
    }

    @Override
    public Date getExpiry() {
        return null;
    }
}
