package com.atlassian.bitbucket.internal.stp;

import com.atlassian.bitbucket.hook.repository.RepositoryHook;
import com.atlassian.bitbucket.hook.repository.RepositoryHookService;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.util.Page;
import com.atlassian.bitbucket.util.PageProvider;
import com.atlassian.bitbucket.util.PageRequest;
import com.atlassian.bitbucket.util.PagedIterable;
import com.atlassian.support.tools.spi.SupportInfoAppender;
import com.atlassian.support.tools.spi.SupportInfoBuilder;
import com.google.common.base.Predicate;
import com.google.common.collect.Iterables;

/**
 * Adds information about {@link RepositoryHook repository hooks} to STP.
 * <p>
 * Information about hook <i>files</i> is SCM-specific and must be added by the SCM's own plugin. For the bundled
 * Git SCM, see {@code GitHookSupportInfoAppender}.
 *
 * @since 3.10
 */
public class RepositoryHookSupportInfo implements SupportInfoAppender<Repository> {

    private static final Predicate<RepositoryHook> IS_ENABLED = new Predicate<RepositoryHook>() {

        @Override
        public boolean apply(RepositoryHook hook) {
            return hook.isEnabled();
        }
    };

    private final RepositoryHookService repositoryHookService;

    public RepositoryHookSupportInfo(RepositoryHookService repositoryHookService) {
        this.repositoryHookService = repositoryHookService;
    }

    @Override
    public void addSupportInfo(SupportInfoBuilder builder, final Repository repository) {
        PageProvider<RepositoryHook> pageProvider = new PageProvider<RepositoryHook>() {

            @Override
            public Page<RepositoryHook> get(PageRequest request) {
                return repositoryHookService.findAll(repository, request);
            }
        };

        builder = builder.addCategory(StpKeys.REPOSITORY_HOOKS);
        for (RepositoryHook hook : Iterables.filter(new PagedIterable<>(pageProvider, 500), IS_ENABLED)) {
            SupportInfoBuilder hookBuilder = builder.addCategory(StpKeys.REPOSITORY_HOOK);
            hookBuilder.addValue(StpKeys.REPOSITORY_HOOK_KEY, hook.getDetails().getKey());
            hookBuilder.addValue(StpKeys.REPOSITORY_HOOK_CONFIG, Boolean.toString(hook.isConfigured()));
            hookBuilder.addContext(hook);
        }
    }
}
