package com.atlassian.bitbucket.mesh.config;

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

import javax.annotation.Nonnull;

import static com.atlassian.bitbucket.mesh.rpc.ManagedConfigurationProperties.COMMIT_MESSAGE_MAX;

class DefaultGitConfig implements GitConfig {

    private static final String PROP_EXECUTABLE = "git.path.executable";

    private final GitCompatibilityConfig compatibilityConfig;
    private final Environment environment;
    private final DefaultGcConfig gcConfig;
    private final GitBinary gitBinary;
    private final DefaultHooksConfig hooksConfig;
    private final DefaultHookScriptsConfig hookScriptsConfig;
    private final DefaultHostingConfig hostingConfig;
    private final GitProcessConfig processConfig;

    private volatile Settings current;

    DefaultGitConfig(Environment environment, GitBinaryHelper gitBinaryHelper) {
        this.environment = environment;

        current = new Settings(environment);
        gitBinary = gitBinaryHelper.find(environment.getProperty(PROP_EXECUTABLE));
        compatibilityConfig = new DefaultGitCompatibilityConfig(gitBinary, environment);
        gcConfig = new DefaultGcConfig(gitBinary, environment);
        hooksConfig = new DefaultHooksConfig(environment);
        hookScriptsConfig = new DefaultHookScriptsConfig(environment);
        hostingConfig = new DefaultHostingConfig(environment);
        processConfig = new DefaultGitProcessConfig(environment);
    }

    @Nonnull
    @Override
    public GitBinary getBinary() {
        return gitBinary;
    }

    @Nonnull
    @Override
    public GitCompatibilityConfig getCompatibility() {
        return compatibilityConfig;
    }

    @Nonnull
    @Override
    public GcConfig getGc() {
        return gcConfig;
    }

    @Nonnull
    @Override
    public HooksConfig getHooks() {
        return hooksConfig;
    }

    @Nonnull
    @Override
    public HookScriptsConfig getHookScripts() {
        return hookScriptsConfig;
    }

    @Nonnull
    @Override
    public HostingConfig getHosting() {
        return hostingConfig;
    }

    @Override
    public int getMaxMessageLength() {
        return current.maxMessageLength;
    }

    @Nonnull
    @Override
    public GitProcessConfig getProcess() {
        return processConfig;
    }

    void reload() {
        current = new Settings(environment);
        gcConfig.reload();
        hooksConfig.reload();
        hookScriptsConfig.reload();
        hostingConfig.reload();
    }

    private static class Settings {

        private final int maxMessageLength;

        Settings(Environment environment) {
            maxMessageLength = environment.getProperty(COMMIT_MESSAGE_MAX, Integer.class, 262144);
        }
    }
}
