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

import com.atlassian.analytics.api.annotations.EventName;
import com.atlassian.bitbucket.event.ApplicationEvent;
import com.atlassian.stash.internal.notification.usersettings.SendMode;
import com.atlassian.bitbucket.user.ApplicationUser;
import com.atlassian.bitbucket.user.ApplicationUserEquality;

import javax.annotation.Nonnull;

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

/**
 * Event raised when a user's notification sending preference is changed.
 *
 * @since 3.4
 */
public class NotificationSendModePreferenceChangeEvent extends ApplicationEvent {

    private static final String BASE_EVENT_NAME = "stash.notification.modechanged.";

    private final ApplicationUser affectedUser;
    private final SendMode defaultSendMode;
    private final SendMode newSendMode;

    /**
     * Constructs a new {@code NotificationSendModePreferenceChangeEvent}. <i>All parameters are required</i>
     *
     * @param source the component raising the event
     * @param affectedUser the user whose preference was changed
     * @param newSendMode the {@link SendMode} that the user's preference was changed to
     * @param defaultSendMode the {@link SendMode} that is the system default
     */
    public NotificationSendModePreferenceChangeEvent(@Nonnull Object source,
                                                     @Nonnull ApplicationUser affectedUser,
                                                     @Nonnull SendMode newSendMode,
                                                     @Nonnull SendMode defaultSendMode) {
        super(source);

        this.affectedUser = checkNotNull(affectedUser, "affectedUser");
        this.defaultSendMode = checkNotNull(defaultSendMode, "defaultSendMode");
        this.newSendMode = checkNotNull(newSendMode, "newSendMode");
    }

    /**
     * @return the {@link ApplicationUser} whose notification preference changed
     */
    @Nonnull
    public ApplicationUser getAffectedUser() {
        return affectedUser;
    }

    /**
     * <i>Note:</i> this property is not used for analytics, instead the {@link #newSendMode} is
     * encapsulated in the analytics event name as generated by {@link #getAnalyticsEventName}.
     *
     * @return the {@link SendMode} that the affectedUser's preference changed to
     */
    @Nonnull
    public SendMode getNewSendMode() {
        return newSendMode;
    }

    /**
     * @return the system default {@link SendMode}
     */
    @Nonnull
    public SendMode getDefaultSendMode() {
        return defaultSendMode;
    }


    /**
     * This is a convenience property to easily be able to tell from the analytics data whether
     * this was a user changing their own setting, or the setting being changed by an admin user via
     * the REST endpoint.
     *
     * @return {@code true} if the user is changing their own preference
     */
    public boolean getUserIsAffectedUser() {
        return ApplicationUserEquality.equals(getUser(), affectedUser);
    }

    /**
     * @return an analytics event name that includes the {@link #newSendMode}
     */
    @EventName
    public String getAnalyticsEventName() {
        return BASE_EVENT_NAME + newSendMode.toString().toLowerCase();
    }
}
