package com.atlassian.bitbucket.mesh.git.gc;

import com.atlassian.bitbucket.mesh.config.GcConfig;
import com.atlassian.bitbucket.mesh.git.GitRepositoryLayout;
import com.atlassian.bitbucket.mesh.git.builder.GitProcessBuilderFactory;
import com.atlassian.bitbucket.mesh.repository.Repository;

import javax.annotation.Nonnull;

/**
 * Performs 'standard' garbage collection in a repository.
 */
class StandardGc implements GcOperation {

    private final GitProcessBuilderFactory builderFactory;
    private final GcConfig config;
    private final PackRefsOperation packRefsOperation;
    private final RepackOperation repackOperation;
    private final Repository repository;
    private final GitRepositoryLayout repositoryLayout;

    StandardGc(GitProcessBuilderFactory builderFactory, GcConfig config,
               Repository repository, GitRepositoryLayout repositoryLayout) {
        this.builderFactory = builderFactory;
        this.config = config;
        this.repository = repository;
        this.repositoryLayout = repositoryLayout;

        packRefsOperation = new PackRefsOperation(builderFactory, config, repository, repositoryLayout);
        repackOperation = new RepackOperation(builderFactory, config, repository, repositoryLayout);
    }

    @Override
    public void run(@Nonnull GcContext context) {
        repackOperation.run(context);
        packRefsOperation.run(context);

        if (context.isSuccess(GcActionType.REPACK) || context.isSuccess(GcActionType.PACK_REFS)) {
            new WriteCommitGraphOperation(builderFactory, config, repository, repositoryLayout).run(context);
            new PruneStaleObjectsOperation(repository, config, repositoryLayout).run(context);
        }
    }

    @Override
    public boolean shouldRun() {
        return packRefsOperation.shouldRun() || repackOperation.shouldRun();
    }
}
