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

import com.atlassian.bitbucket.i18n.I18nService;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.scm.git.command.GitScmCommandBuilder;
import com.atlassian.bitbucket.server.ApplicationPropertiesService;

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

/**
 * Sets {@code HOME} for all {@link GitScmCommandBuilder builders}, ensuring they do not honor any {@code .gitconfig}
 * in the home directory of the user running the tests. This ensures our builds are more consistent by preventing any
 * local user settings from altering Git's behavior.
 * <p>
 * This was introduced prior to the release of 3.5, but backported through to 2.11 to support the matrix builds for
 * older versions as well.
 */
public class MatrixGitCommandBuilderFactory extends DefaultGitCommandBuilderFactory {

    private final ApplicationPropertiesService propertiesService;

    public MatrixGitCommandBuilderFactory(InternalGitScmConfig config, I18nService i18nService,
                                          ApplicationPropertiesService propertiesService) {
        super(config, Collections.<GitCommandBuilderConfigurer>emptyList(), i18nService);

        this.propertiesService = propertiesService;
    }

    @Nonnull
    @Override
    public GitScmCommandBuilder builder(Repository repository) {
        return configure(super.builder(repository));
    }

    /**
     * Ensure we don't process any global configuration files when running the tests; they can throw off our settings.
     * To avoid them:
     * <ul>
     *     <li>Export {@code GIT_CONFIG_NAME} to "1" so that {@code /etc/gitconfig} will not be parsed</li>
     *     <li>Export {@code HOME} to {@code STASH_HOME} so {@code git config} looks in that directory for
     *     {@code .gitconfig} (and won't find it)</li>
     * </ul>
     *
     * @param builder the builder to configure
     * @return the provided {@code builder}
     */
    private GitScmCommandBuilder configure(@Nonnull GitScmCommandBuilder builder) {
        builder.withEnvironment("GIT_CONFIG_NOSYSTEM", "1")
                .withEnvironment("HOME", propertiesService.getHomeDir().getAbsolutePath());

        return builder;
    }
}
