package com.atlassian.bitbucket.mesh;

import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;

import java.util.LinkedHashMap;
import java.util.Map;

public abstract class AbstractDynamicPropertyInitializer
        implements ApplicationContextInitializer<ConfigurableApplicationContext> {

    @Override
    public void initialize(ConfigurableApplicationContext configurableApplicationContext) {
        Map<String, Object> properties = getDynamicProperties();
        applyProperties(configurableApplicationContext, properties);
    }

    protected abstract Map<String, Object> getDynamicProperties();

    private void applyProperties(ConfigurableApplicationContext configurableApplicationContext,
                                 Map<String, Object> properties) {
        ConfigurableEnvironment environment = configurableApplicationContext.getEnvironment();
        MutablePropertySources sources = environment.getPropertySources();
        String name = getClass().getName();
        if (sources.contains(name)) {
            PropertySource<?> source = sources.get(name);
            if (source instanceof Map<?, ?>) {
                @SuppressWarnings("unchecked")
                Map<String, Object> mapSource = (Map<String, Object>) source;
                mapSource.putAll(properties);
            }
        } else {
            Map<String, Object> source = new LinkedHashMap<>(properties);
            sources.addFirst(new MapPropertySource(name, source));
        }
    }
}
