package com.atlassian.bitbucket.user;

import com.atlassian.bitbucket.event.auth.AuthenticationSuccessEvent;

import javax.annotation.Nullable;
import java.util.Date;

/**
 * Extends a {@link ApplicationUser} with additional details relating to the directory backing the user.
 */
public interface DetailedUser extends ApplicationUser {

    /**
     * Retrieves the name of the underlying directory in which this user is stored.
     * <p>
     * In certain circumstances, it may not be possible to determine the directory name. However, while this property
     * is {@code Nullable}, it will generally be available.
     *
     * @return the directory name
     */
    @Nullable
    String getDirectoryName();

    /**
     * Retrieves the timestamp for the user's most recent authentication. This timestamp may be {@code null} if:
     * <ul>
     *     <li>The user has never authenticated</li>
     *     <li>The user's most recent authentication was before this timestamp was added</li>
     * </ul>
     * <p>
     * The exact avenues for "authenticating" vary. The <i>base system</i>, without any custom plugins, tracks
     * authentication for the following:
     * <ul>
     *     <li>HTTP authentication via REST or the web UI</li>
     *     <li>SSH authentication for SCM hosting and other operations</li>
     *     <li>Authentication via Trusted Apps</li>
     * </ul>
     * Plugins can add their own authentication paths. If they raise
     * {@link AuthenticationSuccessEvent AuthenticationSuccessEvent}s for successful
     * attempts, they will be included in this tracking.
     *
     * @return the user's most recent authentication, or {@code null}
     */
    @Nullable
    Date getLastAuthenticationTimestamp();

    /**
     * Retrieves a flag indicating whether the directory in which this user is stored supports deleting the user.
     *
     * @return {@code true} if the underlying directory supports deleting users; otherwise, {@code false}
     */
    boolean isDeletable();

    /**
     * Retrieves a flag indicating whether the directory in which this user is stored supports updating the user's
     * details, such as {@link #getDisplayName() display name} and {@link #getEmailAddress() e-mail address}.
     *
     * @return {@code true} if the underlying directory supports changing details; otherwise, {@code false}
     */
    boolean isMutableDetails();

    /**
     * Retrieves a flag indicating whether the directory in which this user is stored supports modifying the user's
     * groups, either to add new groups or remove existing ones.
     *
     * @return {@code true} if the underlying directory supports changing groups; otherwise, {@code false}
     */
    boolean isMutableGroups();
}
