package com.atlassian.bitbucket.mesh.config;

import com.atlassian.bitbucket.mesh.git.binary.GitBinary;
import com.atlassian.bitbucket.mesh.util.Version;
import org.springframework.core.env.Environment;

public class DefaultGitCompatibilityConfig implements GitCompatibilityConfig {

    private static final String PROP_PACKED_REFS_CALLBACKS = "git.version.packed-refs-backend-callbacks-suppressed";
    private static final String PROP_REF_DELETE_FIXED = "git.version.ref-delete-callbacks-fixed";
    private static final Version VERSION_2_37 = new Version(2, 37);

    private final GitBinary binary;
    private final Environment environment;

    private volatile Settings current;

    public DefaultGitCompatibilityConfig(GitBinary binary, Environment environment) {
        this.binary = binary;
        this.environment = environment;

        reload();
    }

    @Override
    public boolean isPackedRefsBackendCallbacksSuppressed() {
        return current.packedRefsBackendCallbacksSuppressed;
    }

    @Override
    public boolean isRefDeleteCallbacksBroken() {
        return current.refDeleteCallbacksBroken;
    }

    void reload() {
        current = new Settings(binary, environment);
    }

    private static class Settings {

        private final boolean packedRefsBackendCallbacksSuppressed;
        private final boolean refDeleteCallbacksBroken;

        Settings(GitBinary binary, Environment environment) {
            Version curVersion = binary.getVersion();
            if (curVersion.compareTo(VERSION_2_37) < 0) {
                //For git 2.36 and below, we know for sure that the reference-transaction issues have not yet been fixed
                packedRefsBackendCallbacksSuppressed = false;
                refDeleteCallbacksBroken = true;
            } else {
                //Both reference-transaction issues _should_ be fixed in 2.37, but at the time of writing 2.37 had
                //not been released yet. So we support overriding the versions at which these issues have been fixed
                //just in case.
                Version packedRefsBackedVersion =
                        new Version(environment.getProperty(PROP_PACKED_REFS_CALLBACKS, "2.37"));
                packedRefsBackendCallbacksSuppressed = curVersion.compareTo(packedRefsBackedVersion) >= 0;
                Version refDeleteFixedVersion = new Version(environment.getProperty(PROP_REF_DELETE_FIXED, "2.37"));
                refDeleteCallbacksBroken = curVersion.compareTo(refDeleteFixedVersion) < 0;
            }
        }
    }
}
