package com.atlassian.bitbucket.internal.scm.git.lfs.embedded;

import com.atlassian.bitbucket.repository.Repository;

import javax.annotation.Nonnull;
import javax.ws.rs.core.StreamingOutput;
import java.io.IOException;
import java.io.InputStream;

public interface EmbeddedStoreService {

    /**
     * Delete all Git LFS content associated with the given hierarchy. Note that this action is destructive
     * and irreversible.
     *
     * @param repository the repository for which all Git LFS data is to be deleted
     */
    void delete(@Nonnull Repository repository);

    /**
     * Get the number of bytes of space available for storage of LFS content in the store. This is the actual
     * free space on the filesystem hosting data, minus any minimum free space quantity configured. This method
     * will never return less than 0, however in the case of an error (or obviously if the filesystem is full)
     * it will return zero.
     *
     * @return the number of bytes of space available for storage of LFS content in the store.
     */
    long getFreeSpace();

    /**
     * Check if the object exists in the store for the specified repository.
     *
     * @param repository the repository to search for the object in
     * @param oid        the object id
     * @return true if the object exists, otherwise false
     */
    boolean objectExists(@Nonnull Repository repository, @Nonnull String oid);

    /**
     * Read an object from the backing store
     *
     * @param request details of the request, importantly the repository and the object identifier
     * @return a {@link ObjectStreamingOutput} instance from which the contents of the object can be streamed
     */
    @Nonnull
    ObjectStreamingOutput readObject(@Nonnull ReadObjectRequest request);

    /**
     * Writes an object to the backing store.
     * <p>
     * <ul>
     *     <li>If an object already exists for the given OID it will not be altered</li>
     *     <li>If the OID is not equal to the SHA-256 checksum of the contents of the input data stream the file
     *     corresponding to the passed OID will not be altered</li>
     * </ul>
     *
     * @param repository the repository to which the "oid" belongs
     * @param oid        the object identifier. This must be equal to the SHA-256 checksum of the contents
     *                   of the input data stream
     * @param is         input stream to be streamed out to a file in the backing store.
     * @throws IOException                 if some IO exception occurs while reading from the input stream or
     *                                     writing to the output file.
     * @throws ChecksumValidationException if the OID is not equal to the SHA-256 checksum of
     *                                     the contents of the input data stream
     */
    void writeObject(@Nonnull Repository repository, @Nonnull String oid, @Nonnull InputStream is)
            throws IOException, ChecksumValidationException;
}