package com.atlassian.bitbucket.mesh.repository;

import com.atlassian.bitbucket.mesh.git.ref.RefUpdate;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Nonnull;
import java.util.Set;

/**
 * Defines a component which can be used to generate repository hashes.
 *
 * Usage of this component generally involves first creating a hash of the repository using
 * {@link #calculateHash(Repository)} and then for each push calculate a "transaction hash" using
 * {@link #calculateHash(Set)}. These two hashes can then be combined with {@link #combineHashes(String, String)}
 * with the returned value becoming the new content hash for this repository.
 */
public interface RefHasher {

    String NULL_HASH = StringUtils.repeat('0', 64);

    /**
     * Generates a hash given a list of {@link RefUpdate ref updates}.
     *
     * @param refUpdates the ref updates to use to build the new hash
     * @return the generated hash
     */
    @Nonnull
    String calculateHash(@Nonnull Set<RefUpdate> refUpdates);

    /**
     * Generates a hash from the repository's contents.
     *
     * @param repository the repository to hash
     * @return the generated hash
     */
    @Nonnull
    String calculateHash(@Nonnull Repository repository);

    /**
     * Given two hashes, combine them.
     *
     * @param a the first hash
     * @param b the second hash
     * @return the combined hash
     */
    @Nonnull
    String combineHashes(@Nonnull String a, @Nonnull String b);
}
