package com.atlassian.bitbucket.mesh.git.file;

import com.atlassian.bitbucket.mesh.git.commit.Commit;

import javax.annotation.Nonnull;
import java.nio.file.Path;

public interface EditFileManager {

    /**
     * Edits a file and creates a new commit.
     * <p>
     * This method supports the following:
     * <ul>
     *     <li>Creating new files</li>
     *     <li>Updating existing files</li>
     * </ul>
     * Notably, this method does <i>not</i> support:
     * <ul>
     *     <li>Creating symbolic links</li>
     *     <li>Deleting files</li>
     *     <li>Editing multiple files</li>
     *     <li>Changing executable flags</li>
     * </ul>
     * The new commit with the edit can be created on an existing branch, or as a new branch, but this method
     * does not actually change any branches; {@link #updateRef} must be called to update a ref. The returned
     * commit has been fetched back into the repository, but is <i>unreferenced</i>. If {@link #updateRef} is
     * never called, it will eventually be pruned by garbage collection.
     *
     * @param parameters parameters describing the file to edit
     * @param content    the new content the file should have
     * @return the new commit's hash
     */
    @Nonnull
    String editFile(@Nonnull EditFileParameters parameters, @Nonnull Path content);

    /**
     * Updates the {@link EditFileParameters#getTargetBranch target branch} with the specified new commit.
     *
     * @param parameters parameters describing the file that was edited
     * @param commitId   the new commit's hash, which will be used to update the target branch
     * @return the full new commit
     */
    @Nonnull
    Commit updateRef(@Nonnull EditFileParameters parameters, @Nonnull String commitId);
}
