package de.renew.plugin.command;

import org.junit.jupiter.api.Test;

import de.renew.plugin.PluginManager;

import static de.renew.plugin.LoadHelper.getJar;
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 UnloadCommandTest {

    @Test
    public void testGetDescription() {
        assertEquals("cleans up (deactivates) a plugin", new UnloadCommand().getDescription());
    }

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

    @Test
    public void testExecute() throws AssertionError {

        // empty test
        final String result1 =
            doExecuteSuccessfully(new UnloadCommand(), "TestPlugin UnloadSimple");
        assertTrue(result1.contains("did not find plug-in with name"));


        // simple load / unload
        // given
        assertNull(PluginManager.getInstance().getPluginByName("TestPlugin UnloadSimple"));
        PluginManager.getInstance().loadPlugin(getJar(this.getClass(), "UnloadSimple-main.jar"));
        assertNotNull(PluginManager.getInstance().getPluginByName("TestPlugin UnloadSimple"));

        // when
        final String result2 =
            doExecuteSuccessfully(new UnloadCommand(), "TestPlugin UnloadSimple");

        // then
        assertTrue(result2.contains("TestPlugin UnloadSimple"));
        assertTrue(result2.contains("successfully removed"));

        // example with 2 dependency
        // given
        PluginManager.getInstance()
            .loadPlugin(getJar(this.getClass(), "UnloadComplexTop-main.jar"));
        PluginManager.getInstance()
            .loadPlugin(getJar(this.getClass(), "UnloadComplexBottom1-main.jar"));
        PluginManager.getInstance()
            .loadPlugin(getJar(this.getClass(), "UnloadComplexBottom2-main.jar"));

        assertNotNull(PluginManager.getInstance().getPluginByName("TestPlugin UnloadComplexTop"));
        assertNotNull(
            PluginManager.getInstance().getPluginByName("TestPlugin UnloadComplexBottom1"));
        assertNotNull(
            PluginManager.getInstance().getPluginByName("TestPlugin UnloadComplexBottom2"));

        // first it should fail
        // when
        final String result3 =
            doExecuteSuccessfully(new UnloadCommand(), "TestPlugin UnloadComplexTop", "-v");

        // then
        assertTrue(result3.contains("could not unload"));
        assertTrue(result3.contains("there are plug-ins depending on it"));
        assertTrue(result3.contains("-> plugin TestPlugin UnloadComplexBottom1"));
        assertTrue(result3.contains("-> plugin TestPlugin UnloadComplexBottom2"));

        // and now recursively
        // when
        final String result4 =
            doExecuteSuccessfully(new UnloadCommand(), "TestPlugin UnloadComplexTop", "-r");
        // then
        assertTrue(result4.contains("Recursively unloading"));
        assertTrue(result4.contains("Dependent plug-ins successfully removed"));
        assertTrue(result4.contains("TestPlugin UnloadComplexBottom1"));
        assertTrue(result4.contains("TestPlugin UnloadComplexBottom2"));
        assertTrue(result4.contains("successfully removed"));
        assertTrue(result4.contains("TestPlugin UnloadComplexTop"));

        /*
        // TODO: check LOADER-104
        assertEquals(0, (int) PluginManager.getInstance().getPlugins().stream()
                .filter(p -> "TestPlugin UnloadComplexBottom1".equals(p.getName())
                || "TestPlugin UnloadComplexBottom2".equals(p.getName())
                || "TestPlugin UnloadComplexTop".equals(p.getName()))
                .count());
        */

    }
}
