package com.atlassian.bitbucket.internal.audit.dao;

import com.atlassian.bitbucket.event.audit.AuditEvent;
import com.atlassian.bitbucket.project.Project;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.user.ApplicationUser;
import com.atlassian.bitbucket.util.Page;
import com.atlassian.bitbucket.util.PageRequest;

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

/**
 * A DAO for storing auditable events {@link AuditEvent AuditEvent} against Stash entities
 *
 * @since 2.6
 */
public interface AuditItemDao {

    /**
     * Stores a new audit event against a supplied project
     *
     * @param project the project to store this item against
     * @param user    the user creating the event
     * @param action  the type of event
     * @param date    the time of the event
     * @param details any relevant details
     * @return the stored audit event
     */
    AoProjectAuditEvent storeAuditItem(@Nonnull Project project, @Nullable ApplicationUser user, @Nonnull String action, @Nonnull Date date, @Nullable String details);

    /**
     * Stores a new audit event against a supplied repository
     *
     * @param repository the repository to store this item against
     * @param user       the user creating the event
     * @param action     the type of event
     * @param date       the time of the event
     * @param details    any relevant details
     * @return the stored audit event
     */
    AoRepositoryAuditEvent storeAuditItem(@Nonnull Repository repository, @Nullable ApplicationUser user, @Nonnull String action, @Nonnull Date date, @Nullable String details);

    /**
     * Retrieve the previously stored events for the given project
     *
     * @param project the project
     * @return the previously stored events
     */
    Page<AoProjectAuditEvent> getEvents(@Nonnull Project project, PageRequest pageRequest);

    /**
     * Retrieve the previously stored events for the given repository
     *
     * @param repository the repository
     * @return the previously stored events
     */
    Page<AoRepositoryAuditEvent> getEvents(@Nonnull Repository repository, PageRequest pageRequest);

    /**
     * Trims the project audit events to {@code maximumRows} per project
     *
     * @param maximumRows the maximum number of rows a project can have
     * @param batchSize the number of rows to be cleaned up in one batch, used to prevent long running transactions
     */
    void cleanUpProjectAuditEntries(int maximumRows, int batchSize);

    /**
     * Trims the repository audit events to {@code maximumRows} per repository
     *
     * @param maximumRows the maximum number of rows a repository can have
     * @param batchSize the number of rows to be cleaned up in one batch, used to prevent long running transactions
     */
    void cleanUpRepositoryAuditEntries(int maximumRows, int batchSize);
}
