package com.atlassian.bitbucket.mesh.repository;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

public interface RepositoryAttributeManager {

    /**
     * Deletes all attributes for the specified repository
     *
     * @param repositoryId the repository ID
     */
    void delete(@Nonnull String repositoryId);

    /**
     * Retrieves the content hash for the specified repository.
     *
     * @param repositoryId the repository ID
     * @return a content hash, or {@code null} if no content hash has been set for the given repository
     */
    @Nullable
    String getContentHash(@Nonnull String repositoryId);

    /**
     * Retrieves the metadata hash for the specified repository.
     *
     * @param repositoryId the repository ID
     * @return a metadata hash, or {@code null} if no metadata hash been set for the given repository
     */
    @Nullable
    String getMetadataHash(@Nonnull String repositoryId);

    /**
     * Retrieves the version for the specified repository.
     *
     * @param repositoryId the repository ID
     * @return the version
     */
    long getVersion(@Nonnull String repositoryId);

    /**
     * Retrieves the versions for all managed repositories in the provided set of partitions.
     *
     * @param partitions the partitions to filter by; empty means "any partition"
     * @return the (order preserving) map of matching IDs to their version
     * @since 1.4
     */
    @Nonnull
    Map<String, Long> getVersionsByPartitions(@Nonnull Set<String> partitions);

    /**
     * Increments and returns the version for the specified repository.
     *
     * @param repositoryId the repository ID
     * @return the updated version
     */
    long incrementAndGetVersion(@Nonnull String repositoryId);

    /**
     * Retrieves the read-only status for the specified repository.
     *
     * @param repositoryId the repository ID
     * @return {@code true} if the repository is read-only, otherwise {@code false}
     */
    boolean isReadOnly(@Nonnull String repositoryId);

    /**
     * Replaces the set of read-only repositories with the given one. Specifically, a set of repositories are taken
     * and any repositories not in that set are assumed to be read/write while repositories in the set are read-only.
     *
     * @param repositoryIds the repositories that are read-only
     */
    void replaceReadOnly(@Nonnull Collection<String> repositoryIds);

    /**
     * Stores the content hash for the specified repository.
     *
     * @param repositoryId the repository ID
     * @param contentHash  a content hash, or {@code null} to indicate the absence of a content hash
     */
    void setContentHash(@Nonnull String repositoryId, @Nullable String contentHash);

    /**
     * Stores the metadata hash for the specified repository.
     *
     * @param repositoryId the repository ID
     * @param metadataHash a metadata hash, or {@code null} to indicate the absence of a metadata hash
     */
    void setMetadataHash(@Nonnull String repositoryId, @Nullable String metadataHash);

    /**
     * Enable/disable read-only for the specified repository.
     *
     * @param repositoryId the repository to enable/disable read-only on
     * @param readOnly     {@code true} to enable read-only mode; {@code false} to disable
     */
    void setReadOnly(@Nonnull String repositoryId, boolean readOnly);

    /**
     * Stores the version for the specified repository.
     *
     * @param repositoryId the repository ID
     * @param version      the version
     */
    void setVersion(@Nonnull String repositoryId, long version);
}
