package de.renew.propertymanagement;

import java.net.URL;
import java.util.NoSuchElementException;
import java.util.Optional;

import org.apache.log4j.Logger;

import de.renew.plugin.PluginAdapter;
import de.renew.plugin.PluginException;
import de.renew.plugin.PluginManager;
import de.renew.plugin.PluginProperties;
import de.renew.propertymanagement.commands.GetConfigurablePropertiesCommand;
import de.renew.propertymanagement.prop.ConfigurablePropertyManager;
import de.renew.propertymanagement.prop.PropertyLoadFailedException;

/**
 * The main plugin for the PropertyManagement Plugin.
 * @author 0schult
 */
public class PropertyManagementPlugin extends PluginAdapter {

    /**
     * Logger instance for the PropertyManagementPlugin
     */
    private static final Logger LOGGER = Logger.getLogger(PropertyManagementPlugin.class);

    /**
     * The system property that sets the GUI scale.
     * Has to be loaded before any GUI components are started
     */
    private static final String UI_SCALE_PROPERTY = "sun.java2d.uiScale";

    /**
     * Creates an instance of the PropertyManagement Plugin using the contents of <code>plugin.cfg</code>.
     *
     * @param location an <code>URL</code> pointing to the <code>jar</code>
     *                 file or directory containing the plugin code and
     *                 configuration files.
     * @throws PluginException if an error occurs while loading the plugin or its configuration.
     *                         Possible nested exceptions are:
     *                         <ul>
     *                         <li>{@link java.net.MalformedURLException} if the <code>plugin.cfg</code> URL
     *                             could not be derived from the plugin URL.</li>
     *                         <li>{@link java.io.IOException} if the configuration could not be loaded.</li>
     *                         </ul>
     */
    public PropertyManagementPlugin(URL location) throws PluginException {
        super(location);
    }

    /**
     * Creates the PropertyManagement Plugin with the given PluginProperties.
     *
     * @param props the plugin configuration.
     **/
    public PropertyManagementPlugin(PluginProperties props) {
        super(props);
    }

    /**
     * Initialize the plugin, register menus and commands.
     */
    @Override
    public void init() {
        //manually register the GUI scale to ensure it is set before any GUI elements are created
        ConfigurablePropertyManager propertyManager = ConfigurablePropertyManager.getInstance();
        propertyManager.addConfigurableProperty(
            UI_SCALE_PROPERTY, "1", "Renew Window Management", "UI Scale", null);
        try {
            propertyManager.loadProperties(false);
            propertyManager.loadProperties(true);
            Optional<String> prop = Optional.ofNullable(System.getProperty(UI_SCALE_PROPERTY));
            if (prop.isEmpty()) {
                prop = propertyManager.getCurrentValueForProperty(UI_SCALE_PROPERTY);
            }
            prop.ifPresent(value -> System.setProperty(UI_SCALE_PROPERTY, value));
        } catch (NoSuchElementException | PropertyLoadFailedException e) {
            LOGGER.error("Could not load property file.", e);
        }

        PluginManager pm = PluginManager.getInstance();
        if (pm != null) {
            pm.addCLCommand(
                GetConfigurablePropertiesCommand.COMMAND_NAME,
                new GetConfigurablePropertiesCommand());
        }
    }

    /**
     * Unregisters menus and (possible) commands.
     */
    @Override
    public boolean cleanup() {
        PluginManager pm = PluginManager.getInstance();
        if (pm == null) {
            return false;
        }
        pm.removeCLCommand(GetConfigurablePropertiesCommand.COMMAND_NAME);
        return true;
    }
}