package com.atlassian.stash.internal.notification.usersettings;

import com.atlassian.bitbucket.user.ApplicationUser;
import com.atlassian.bitbucket.user.SecurityService;

import javax.annotation.Nonnull;

import static com.google.common.base.Preconditions.checkNotNull;

/**
 * For existing users, a feature discovery banner is shown in the first few batched emails. This class is for getting/
 * setting the states of a user's feature discovery.
 * <p>
 * Note that this class takes care of elevating to the required security context for getting/setting the user settings.
 */
public class BatchEmailFeatureDiscovery {

    static final int HIDE = -1;

    private static final int BATCH_FEATURE_DISCOVERY_SHOW_COUNT = 3;

    private final UserNotificationSettingsService userNotificationSettingsService;
    private final SecurityService securityService;

    public BatchEmailFeatureDiscovery(UserNotificationSettingsService userNotificationSettingsService,
                                      SecurityService securityService) {
        this.userNotificationSettingsService = userNotificationSettingsService;
        this.securityService = securityService;
    }

    /**
     * Checks whether the feature discovery should be shown for a {@link ApplicationUser user}.
     *
     * @param user the user to check
     * @return {@code true} if the user should be shown the feature discovery content
     */
    public boolean shouldShowFeatureDiscovery(@Nonnull final ApplicationUser user) {
        checkNotNull(user, "user");

        return securityService.impersonating(user, "Read user settings for batch email feature discovery")
                .call(() -> {
                    int showCount = getShowCount(user);

                    return showCount != HIDE && showCount < BATCH_FEATURE_DISCOVERY_SHOW_COUNT;
                });
    }

    /**
     * Increments (or sets to 1) the Batch Email feature discovery counter for a {@link ApplicationUser}.
     *
     * @param user the user to increment count for
     */
    public void incrementFeatureDiscoveryShowCount(@Nonnull final ApplicationUser user) {
        checkNotNull(user, "user");

        securityService.impersonating(user, "Write user settings for batch email feature discovery")
                .call(() -> {
                    int showCount = getShowCount(user);
                    UserNotificationSettings newSettings = new UserNotificationSettings.Builder()
                            .batchFeatureDiscoveryShowCount(showCount + 1)
                            .build();
                    userNotificationSettingsService.updateSettingsForUser(user, newSettings);

                    return null;
                });
    }

    /**
     * Update the user's settings so that feature discovery is never shown for them.
     *
     * @param user the user whose settings to update
     */
    public void setNeverShowFeatureDiscovery(@Nonnull final ApplicationUser user) {
        checkNotNull(user, "user");

        securityService.impersonating(user, "Write user settings for batch email feature discovery")
                .call(() -> {
                    UserNotificationSettings settings = new UserNotificationSettings.Builder()
                            .batchFeatureDiscoveryShowCount(BatchEmailFeatureDiscovery.HIDE)
                            .build();
                    userNotificationSettingsService.updateSettingsForUser(user, settings);

                    return null;
                });
    }

    private int getShowCount(ApplicationUser user) {
        return userNotificationSettingsService.getSettingsForUser(user).getBatchFeatureDiscoveryShowCount();
    }
}
