package de.renew.plugin.command;

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

import org.junit.jupiter.api.Test;

import de.renew.plugin.IPlugin;
import de.renew.plugin.PluginManager;
import de.renew.plugin.PluginProperties;

import static de.renew.plugin.LoadHelper.getJar;
import static de.renew.plugin.LoadHelper.isPluginLoaded;
import static de.renew.plugin.command.CommandHelper.doExecuteSuccessfully;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class SetPropertyCommandTest {

    private static final String PLUGIN_NAME = "TestPlugin SetPropertyCommand";

    @Test
    public void testGetArguments() {
        assertEquals("propertyNames", new SetPropertyCommand().getArguments());
    }

    @Test
    public void testGetDescription() {
        assertEquals(
            "sets a system property (syntax key=value)", new SetPropertyCommand().getDescription());
    }

    @Test
    public void testExecute() {
        // result is thankfully unimportant for this test :)
        // setup
        loadPlugin();

        // set property
        doExecuteSuccessfully(new SetPropertyCommand(), "mySystemProperty=mySystemValue");
        final String property =
            PluginProperties.getUserProperties().getProperty("mySystemProperty");
        assertNotNull(property);
        assertEquals("mySystemValue", property);
        assertEquals("mySystemValue", getPluginProperty("mySystemProperty"));

        // remove property
        doExecuteSuccessfully(new SetPropertyCommand(), "mySystemProperty");
        final String property2 =
            PluginProperties.getUserProperties().getProperty("mySystemProperty");
        assertNull(property2);
        assertNull(getPluginProperty("mySystemProperty"));

        // set property
        doExecuteSuccessfully(new SetPropertyCommand(), "mySystemProperty2 = mySystemValue2");
        final String property3 =
            PluginProperties.getUserProperties().getProperty("mySystemProperty2 ");
        assertNotNull(property3);
        assertEquals(" mySystemValue2", property3);
        assertEquals(" mySystemValue2", getPluginProperty("mySystemProperty2 "));

        // remove property
        doExecuteSuccessfully(new SetPropertyCommand(), "mySystemProperty2 =");
        final String property4 =
            PluginProperties.getUserProperties().getProperty("mySystemProperty2 ");
        assertNull(property4);
        assertNull(getPluginProperty("mySystemProperty2 "));


        // empty property is not set
        doExecuteSuccessfully(new SetPropertyCommand(), "mySystemProperty3=");
        final String property5 =
            PluginProperties.getUserProperties().getProperty("mySystemProperty3");
        assertNull(property5);
        assertNull(getPluginProperty("mySystemProperty3"));

        // set multiple properties
        doExecuteSuccessfully(
            new SetPropertyCommand(), "myProperty4=myValue1", "myProperty5=myValue2");
        final String property6 = PluginProperties.getUserProperties().getProperty("myProperty4");
        final String property7 = PluginProperties.getUserProperties().getProperty("myProperty5");
        assertNotNull(property6);
        assertEquals("myValue1", property6);
        assertEquals("myValue1", getPluginProperty("myProperty4"));
        assertNotNull(property7);
        assertEquals("myValue2", property7);
        assertEquals("myValue2", getPluginProperty("myProperty5"));

    }

    private String getPluginProperty(final String name) {
        final Optional<IPlugin> first = PluginManager.getInstance().getPlugins().stream()
            .filter(p -> PLUGIN_NAME.equals(p.getName())).findFirst();
        if (first.isEmpty()) {
            throw new AssertionError("Plugin " + PLUGIN_NAME + " was not loaded beforehand");
        }
        return first.get().getProperties().getProperty(name);
    }

    private void loadPlugin() {
        final URL jar = getJar(this.getClass(), "SetPropertyCommand-main.jar");
        PluginManager.getInstance().loadPlugin(jar);
        assertTrue(isPluginLoaded(PLUGIN_NAME));
    }

}
