package com.atlassian.stash.internal.plugin;

import com.atlassian.plugin.manager.PluginPersistentState;
import com.atlassian.plugin.manager.PluginPersistentStateStore;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class DefaultPluginPersistentStateStore implements PluginPersistentStateStore {

    private final PluginStateDao pluginStateDao;

    public DefaultPluginPersistentStateStore(PluginStateDao pluginStateDao) {
        this.pluginStateDao = pluginStateDao;
    }

    @Transactional(readOnly = true)
    public PluginPersistentState load() {
        Map<String, Boolean> state = new HashMap<>();

        for (PluginState pluginState : pluginStateDao.findAll()) {
            state.put(pluginState.getName(), pluginState.isEnabled());
        }

        return PluginPersistentState.Builder.create().addState(state).toState();
    }

    /**
     * This method executes in a separate transaction because the plugin system expects the save to be persisted even
     * if a surrounding transaction is rolled back.
     *
     * @param state the updated plugin state
     */
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void save(PluginPersistentState state) {
        // clear the database
        pluginStateDao.clear();

        Set<Entry<String, Boolean>> set = state.getMap().entrySet();
        for (Entry<String, Boolean> e : set) {
            pluginStateDao.create(new PluginState(e.getKey(), e.getValue()));
        }
    }
}
