package com.atlassian.stash.internal.plugin.hooks.approvers;

import com.atlassian.event.api.EventListener;
import com.atlassian.event.api.EventPublisher;
import com.atlassian.sal.api.pluginsettings.PluginSettings;
import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;
import com.atlassian.bitbucket.event.repository.RepositoryDeletedEvent;
import com.atlassian.bitbucket.repository.Repository;
import org.apache.commons.lang3.ObjectUtils;

public class RequiredApproversHelper {

    static final String PLUGIN_KEY = "com.atlassian.bitbucket.server.bitbucket-bundled-hooks";
    static final String MODULE_KEY = PLUGIN_KEY + ":required-approvers-settings-soy-templates";
    static final int MAX_APPROVERS = 9;

    private final PluginSettings pluginSettings;
    private final EventPublisher eventPublisher;

    public RequiredApproversHelper(PluginSettingsFactory factory, EventPublisher eventPublisher) {
        this.eventPublisher = eventPublisher;
        this.pluginSettings = factory.createSettingsForKey(PLUGIN_KEY);
    }

    /**
     * Makes sure the plugin setting is deleted if the repository is removed.
     *
     * @param event repository deletion event
     */
    @EventListener
    public void onRepositoryDeleted(RepositoryDeletedEvent event) {
        pluginSettings.remove(createKey(event.getRepository()));
    }

    /**
     * Gets the number of required approvers for all the pull requests targeting this repository.
     *
     * @param repository repository
     * @return number of required approvers
     */
    int getRequiredApproversCount(Repository repository) {
        Object value = pluginSettings.get(createKey(repository));

        if (value instanceof String) {
            try {
                return Integer.parseInt((String) value);
            } catch (NumberFormatException e) {
                // nothing to do
            }
        }

        return 0;
    }

    /**
     * Saves the number of required approvers for all the pull requests targeting this repository.
     *
     * @param repository repository
     * @param count number of required approvers
     */
    void saveRequiredApproversCount(Repository repository, Integer count) {
        Object previousValue = pluginSettings.put(createKey(repository), count == null ? null : count.toString());
        Integer previousValueInteger = previousValue == null ? null : Integer.parseInt((String) previousValue);
        if (ObjectUtils.notEqual(previousValueInteger, count)) {
            eventPublisher.publish(new RequiredApproversChangedEvent(this, repository, count, previousValueInteger));
        }
    }

    private String createKey(Repository repository) {
        return "repo." + repository.getId() + ".requiredApproversCount";
    }

}
