package com.atlassian.bitbucket.internal.mirroring.upstream.dao;

import com.atlassian.bitbucket.internal.mirroring.MirroringRequest;
import com.atlassian.bitbucket.internal.mirroring.MirroringRequestState;
import com.atlassian.bitbucket.internal.mirroring.upstream.MirroringRequestSearchRequest;
import com.atlassian.bitbucket.util.Page;
import com.atlassian.bitbucket.util.PageRequest;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

/**
 * A DAO for persisting {@link MirroringRequest mirroring requests}
 */
public interface MirroringRequestDao {
    /**
     * @return the number of mirroring requests in the supplied state
     */
    int countInState(@Nonnull MirroringRequestState state);

    /**
     * Creates a new request with the starting state of {@link MirroringRequestState#PENDING PENDING}
     */
    @Nonnull
    AoMirroringRequest create(@Nonnull MirroringRequest request);

    /**
     * Deletes an {@link AoMirroringRequest}
     * @return true if the {@link AoMirroringRequest} existed and deleted, false otherwise
     */
    boolean delete(int id);

    /**
     * Finds all {@link AoMirroringRequest AoMirroringRequests} within the bounds of the page request.
     */
    @Nonnull
    Page<AoMirroringRequest> findAll(@Nonnull PageRequest pageRequest);

    /**
     * Finds all {@link AoMirroringRequest AoMirroringRequests} that match the criteria within the bounds of the page request.
     */
    @Nonnull
    Page<AoMirroringRequest> findAll(MirroringRequestSearchRequest searchRequest, PageRequest pageRequest);

    /**
     * Finds all {@link AoMirroringRequest AoMirroringRequests} for the mirror with the supplied id within the bounds of the page request
     */
    @Nonnull
    Page<AoMirroringRequest> findByMirrorId(@Nonnull String mirrorId, @Nonnull PageRequest pageRequest);

    /**
     * @return an {@link AoMirroringRequest} with the specified id or null if no such request exists
     */
    @Nullable
    AoMirroringRequest getById(int id);

    /**
     * Updates an {@link AoMirroringRequest} to the {@link MirroringRequestState#REJECTED REJECTED} state.
     */
    @Nonnull
    AoMirroringRequest resolve(int id, @Nonnull MirroringRequestState resolution, int resolverUserId);
}
