package com.atlassian.stash.internal.scm.git;

import com.atlassian.bitbucket.Product;
import com.atlassian.bitbucket.scm.git.GitConstants;

import java.util.Locale;

/**
 * Contains constants that are reused throughout the implementation of the Git plugin but which are not considered
 * suitable for including in the {@link GitConstants public API}.
 *
 * @since 2.9
 */
public class InternalGitConstants extends GitConstants {

    /**
     * The value for {@link com.atlassian.bitbucket.scm.git.command.config.GitConfig#GC_AUTO gc.auto} that means
     * automatic garbage collection is disabled.
     *
     * @since 4.6
     */
    public static final String CONFIG_GC_AUTO_DISABLED = "0";
    /**
     * The value for {@link com.atlassian.bitbucket.scm.git.command.config.GitConfig#GC_PRUNE_EXPIRE gc.pruneexpire}
     * that means unreachable objects should never be pruned.
     *
     * @since 4.6
     */
    public static final String CONFIG_GC_PRUNE_EXPIRE_NEVER = "never";

    /**
     * This environment variable may be exported to cause {@code git} to look up objects in the specified directory or
     * directories (separated by a colon, even on Windows) <i>in addition to</i> the {@link #PATH_OBJECTS objects}
     * directory within the repository where the command is executed.
     */
    public static final String ENV_ALTERNATE_OBJECT_DIRS = "GIT_ALTERNATE_OBJECT_DIRECTORIES";
    /**
     * This environment variable may be exported to cause {@code git} to look up objects in the specified directory
     * <i>instead of</i> the {@link #PATH_OBJECTS objects} directory within the repository where the command is
     * executed.
     */
    public static final String ENV_OBJECT_DIR = "GIT_OBJECT_DIRECTORY";

    /**
     * This file contains packed references. It is created/updated when {@code git gc} runs, and may also be updated by
     * running {@code git pack-refs}. In general, references are contained one per line, and may reference branches and
     * tags. Lines starting with a # represent comments. Entries for tags may span two lines, where the second line is
     * the hash of the tagged reference (and the first is the hash and name of the tag itself).
     * <p>
     * An example of the file's contents looks like this:
     * <code>
     *     <pre>
     * # pack-refs with: peeled
     * d6edcbf924697ab811a867421dab60d954ccad99 refs/heads/basic_branching
     * 6053a1eaa1c009dd11092d09a72f3c41af1b59ad refs/heads/branch_mod_merge
     * 0a943a29376f2336b78312d99e65da17048951db refs/heads/master
     * 2e10dd2d1d5eea9291b296e78312e8a703964a95 refs/heads/out_of_order_branch
     * 80aa5be5ecf39660f798858482254f7a2ae9110e refs/tags/backdated_annotated_tag
     * ^57150c54c38d6570b2fd5e6d6cfc19476de44e84
     * 9b4e781dea0769888fe270e06ad76675f73851b1 refs/tags/retagged_signed_tag
     * ^0a943a29376f2336b78312d99e65da17048951db
     * 12ebe2a58367347cd39f19f5a72f3cbec7b8f9a9 refs/tags/signed_tag
     * ^0a943a29376f2336b78312d99e65da17048951db
     * 6053a1eaa1c009dd11092d09a72f3c41af1b59ad refs/tags/simple_tag
     *     </pre>
     * </code>
     * Notice that the last tag only covers one line; that represents a lightweight tag, which has no hash of its own.
     * The hash shown is for the commit that was tagged. The other tags are annotated or signed as indicated in their
     * name--there are no differences in their representation in the packed-refs file.
     */
    public static final String PACKED_REFS = "packed-refs";
    /**
     * The path under {@link #PATH_OBJECTS objects/}{@link #PATH_INFO info/} where alternates are stored. This file
     * lists <i>absolute paths</i> to {@link #PATH_OBJECTS objects/} directories within other Git repositories, allowing
     * objects to be "borrowed" between repositories.
     */
    public static final String PATH_ALTERNATES = "alternates";
    /**
     * The path under {@link #PATH_OBJECTS objects/}{@link #PATH_INFO info/} where path attributes are stored. These
     * attributes affect how Git interacts with files in the associated repository. For example, they can be used to
     * control how long conflict markers are or to indicate that specific file types contain text.
     */
    public static final String PATH_ATTRIBUTES = "attributes";
    /**
     * The {@code libexec} path where core binaries are stored.
     *
     * @since 3.1
     */
    public static final String PATH_GIT_CORE = "git-core";
    /**
     * The path within a non-bare clone to the real Git repository.
     */
    public static final String PATH_GIT = ".git";
    /**
     * The path within a Git repository where special information files are stored. {@link #PATH_ALTERNATES alternates}
     * and {@link #PATH_ATTRIBUTES attributes} are stored here, in addition to pack details for "dumb" HTTP.
     */
    public static final String PATH_INFO = "info";
    /**
     * The path within a Git repository where reflogs are written.
     */
    public static final String PATH_LOGS = "logs";
    /**
     * The path within a Git repository where objects (loose or packed) are written. Packed objects will be in a
     * {@code pack} subdirectory, with loose objects stored in 2-character subdirectories (to optimise lookup).
     */
    public static final String PATH_OBJECTS = "objects";
    /**
     * The path within the {@link #PATH_OBJECTS objects} directory where pack files are written.
     *
     * @since 3.9
     */
    public static final String PATH_PACK = "pack";
    /**
     * The path under {@link #PATH_REFS refs/} or {@link #PATH_STASH_REFS stash-refs/} where pull request refs
     * are stored.
     */
    public static final String PATH_PULL_REQUESTS = "pull-requests";
    /**
     * The path within a Git repository where all <i>publicly advertised</i> refs are stored. Loose refs are stored
     * under this directory, and {@link #PACKED_REFS packed refs} will have a qualified path beginning with this.
     */
    public static final String PATH_REFS = "refs";
    /**
     * The path within a Git repository where the system stores its "dark" refs. <i>These are not considered refs by
     * Git, and will not be included in ref advertisements, nor will they ever be packed.</i>
     */
    public static final String PATH_STASH_REFS = "stash-" + PATH_REFS;
    /**
     * Similar to {@link #PACKED_REFS packed-refs}, {@code stash-packed-refs} contains packed refs. However, unlike
     * {@code packed-refs}, Git does not maintain (or even recognize) {@code stash-packed-refs}.
     * <p>
     * As of 2.9, {@code stash-packed-refs} is created as part of cleaning up pull request refs. The refs contained
     * here are excised snippets removed from {@code packed-refs} to remove them from the ref advertisement as part
     * of that cleanup. This file is never <i>grown</i>; it is only read from and slowly unpacked into loose refs as
     * pull requests are viewed. The existence of, and complexity stemming from, this file is a trade off for speed
     * in cleaning up pull request refs.
     * <p>
     * This file has the same format as {@code packed-refs}, except that it will never contain tags.
     */
    public static final String STASH_PACKED_REFS = "stash-" + PACKED_REFS;
    /**
     * The subpath for the {@link #PATH_ALTERNATES alternates} file within a <i>bare</i> Git repository.
     *
     * @see #PATH_ALTERNATES
     */
    public static final String[] SUBPATH_ALTERNATES = {PATH_OBJECTS, PATH_INFO, PATH_ALTERNATES};
    /**
     * A placeholder display name to use when there is no context user available and an operation is performed which
     * requires author/committer/tagger details.
     */
    public static final String SYSTEM_DISPLAY_NAME = Product.NAME;
    /**
     * A placeholder e-mail address to use when there is no context user available and an operation is performed
     * which require author/committer/tagger details.
     */
    public static final String SYSTEM_EMAIL_ADDRESS = Product.NAME.toLowerCase(Locale.US) + "@atlassian.com";
}
