package com.atlassian.stash.internal.idx;

import com.atlassian.plugin.ModuleDescriptor;
import com.atlassian.plugin.PluginAccessor;
import com.atlassian.bitbucket.idx.CommitPropertyConfiguration;
import com.atlassian.bitbucket.idx.CommitPropertyConfigurationModuleDescriptor;
import com.atlassian.bitbucket.repository.Repository;
import com.google.common.collect.ImmutableSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Nonnull;
import java.util.Collection;
import java.util.stream.Stream;

import static com.atlassian.bitbucket.util.ModuleDescriptorUtils.toModules;

/**
 * This {@link CommitPropertyConfiguration} is only available within the host container. It delegates to any
 * {@code CommitPropertyConfiguration}s that are configured within plugins.
 */
@Component
public class PluggableCommitPropertyConfiguration implements CommitPropertyConfiguration {

    private final PluginAccessor pluginAccessor;

    @Autowired
    public PluggableCommitPropertyConfiguration(PluginAccessor pluginAccessor) {
        this.pluginAccessor = pluginAccessor;
    }

    @Nonnull
    @Override
    public Collection<String> getPropertiesToPreload(Repository repository) {
        ImmutableSet.Builder<String> properties = ImmutableSet.builder();
        getModules(CommitPropertyConfigurationModuleDescriptor.class).forEach(config ->
                properties.addAll(config.getPropertiesToPreload(repository))
        );

        return properties.build();
    }

    private <M, MD extends ModuleDescriptor<M>> Stream<M> getModules(Class<MD> descriptorClass) {
        return toModules(pluginAccessor.getEnabledModuleDescriptorsByClass(descriptorClass));
    }
}
