/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.catalina;

import java.util.Iterator;

/**
 * Abstract representation of a database of {@link User}s and {@link Group}s that can be maintained by an application,
 * along with definitions of corresponding {@link Role}s, and referenced by a {@link Realm} for authentication and
 * access control.
 *
 * @since 4.1
 */
public interface UserDatabase {

    // ------------------------------------------------------------- Properties

    /**
     * Get the set of {@link Group}s defined in this user database.
     *
     * @return the set of {@link Group}s defined in this user database.
     */
    Iterator<Group> getGroups();


    /**
     * Get the unique global identifier of this user database.
     *
     * @return the unique global identifier of this user database.
     */
    String getId();


    /**
     * Get the set of {@link Role}s defined in this user database.
     *
     * @return the set of {@link Role}s defined in this user database.
     */
    Iterator<Role> getRoles();


    /**
     * Get the set of {@link User}s defined in this user database.
     *
     * @return the set of {@link User}s defined in this user database.
     */
    Iterator<User> getUsers();


    // --------------------------------------------------------- Public Methods

    /**
     * Finalize access to this user database.
     *
     * @exception Exception if any exception is thrown during closing
     */
    void close() throws Exception;


    /**
     * Create and return a new {@link Group} defined in this user database.
     *
     * @param groupname   The group name of the new group (must be unique)
     * @param description The description of this group
     *
     * @return The new group, or {@code null} if there's a pre-existing group
     */
    Group createGroup(String groupname, String description);


    /**
     * Create and return a new {@link Role} defined in this user database.
     *
     * @param rolename    The role name of the new role (must be unique)
     * @param description The description of this role
     *
     * @return The new role, or {@code null} if there's a pre-existing role
     */
    Role createRole(String rolename, String description);


    /**
     * Create and return a new {@link User} defined in this user database.
     *
     * @param username The logon username of the new user (must be unique)
     * @param password The logon password of the new user
     * @param fullName The full name of the new user
     *
     * @return The new user, or {@code null} if there's a pre-existing user
     */
    User createUser(String username, String password, String fullName);


    /**
     * Find the {@link Group} with the specified group name.
     *
     * @param groupname Name of the group to return
     * @return the {@link Group} with the specified group name, if any; otherwise return <code>null</code>.
     */
    Group findGroup(String groupname);


    /**
     * Find the {@link Role} with the specified role name.
     *
     * @param rolename Name of the role to return
     * @return the {@link Role} with the specified role name, if any; otherwise return <code>null</code>.
     */
    Role findRole(String rolename);


    /**
     * Find the {@link User} with the specified username.
     *
     * @param username Name of the user to return
     * @return the {@link User} with the specified username, if any; otherwise return <code>null</code>.
     */
    User findUser(String username);


    /**
     * Initialize access to this user database.
     *
     * @exception Exception if any exception is thrown during opening
     */
    void open() throws Exception;


    /**
     * Remove the specified {@link Group} from this user database.
     *
     * @param group The group to be removed
     */
    void removeGroup(Group group);


    /**
     * Remove the specified {@link Role} from this user database.
     *
     * @param role The role to be removed
     */
    void removeRole(Role role);


    /**
     * Remove the specified {@link User} from this user database.
     *
     * @param user The user to be removed
     */
    void removeUser(User user);


    /**
     * Signal the specified {@link Group} from this user database has been modified.
     *
     * @param group The group that has been modified
     */
    default void modifiedGroup(Group group) {
    }


    /**
     * Signal the specified {@link Role} from this user database has been modified.
     *
     * @param role The role that has been modified
     */
    default void modifiedRole(Role role) {
    }


    /**
     * Signal the specified {@link User} from this user database has been modified.
     *
     * @param user The user that has been modified
     */
    default void modifiedUser(User user) {
    }


    /**
     * Save any updated information to the persistent storage location for this user database.
     *
     * @exception Exception if any exception is thrown during saving
     */
    void save() throws Exception;


    /**
     * Perform any background processing (e.g. checking for changes in persisted storage) required for the user
     * database.
     */
    default void backgroundProcess() {
        // NO-OP by default
    }


    /**
     * Is the database available.
     *
     * @return true
     */
    default boolean isAvailable() {
        return true;
    }


    /**
     * Is the database data loaded on demand. This is used to avoid eager loading of the full database data, for example
     * for JMX registration of all objects.
     *
     * @return false
     */
    default boolean isSparse() {
        return false;
    }
}
