package com.atlassian.bitbucket.installer.scripts;

import org.apache.commons.io.FileUtils;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.TemporaryFolder;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties;

import static com.atlassian.bitbucket.installer.InstallerConstants.KEY_APP_BITBUCKET_HOME;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Mockito.*;

@SuppressWarnings("deprecation")
public class ConfirmDisablePluginsScreenTest extends BaseInstallerTest {

    @Rule
    public final TemporaryFolder temporaryFolder = new TemporaryFolder();

    private ConfirmDisablePluginsScreen screen;

    @Before
    public void setup() {
        screen = new ConfirmDisablePluginsScreen(getContext(), getUtils());

        when(getContext().getVariable(KEY_APP_BITBUCKET_HOME)).thenReturn(temporaryFolder.getRoot().getAbsolutePath());
    }

    @Test
    public void testShouldShowScreen() throws IOException {
        setUpgrade();

        setupPluginsFolders();

        FileUtils.touch(new File(temporaryFolder.getRoot(), "shared/plugins/installed-plugins/plugin.obr"));

        assertTrue(screen.shouldShowScreen());
    }

    @Test
    public void testShouldShowScreenWithGarbageFile() throws IOException {
        setUpgrade();

        setupPluginsFolders();

        FileUtils.touch(new File(temporaryFolder.getRoot(), "shared/plugins/installed-plugins/garbage"));

        assertFalse(screen.shouldShowScreen());
    }

    @Test
    public void testShouldShowScreenWithLegacyPluginsLocation() throws IOException {
        setUpgrade();

        setupPluginsFolders();

        FileUtils.touch(new File(temporaryFolder.getRoot(), "plugins/installed-plugins/plugin.obr"));

        assertTrue(screen.shouldShowScreen());
    }

    @Test
    public void testShouldShowScreenWithGarbageFileInLegacyLocation() throws IOException {
        setUpgrade();

        setupPluginsFolders();

        FileUtils.touch(new File(temporaryFolder.getRoot(), "plugins/installed-plugins/garbage"));

        assertFalse(screen.shouldShowScreen());
    }

    @Test
    public void testShouldShowScreenWithoutPlugins() throws IOException {
        setUpgrade();

        setupPluginsFolders();

        assertFalse(screen.shouldShowScreen());
    }

    @Test
    public void testShouldShowScreenWithNewInstall() {
        setDefaultInstall();

        assertFalse(screen.shouldShowScreen());
    }

    @Test
    public void testShouldShowScreenWithoutVersionFile() {
        setUpgrade();

        assertFalse(screen.shouldShowScreen());
    }

    @Test
    public void testShouldShowScreenWhenUpgradingBitbucket() throws IOException {
        setUpgrade();

        setupPluginsFolders("4.0.0");
        FileUtils.touch(new File(temporaryFolder.getRoot(), "shared/plugins/installed-plugins/plugin.obr"));

        assertFalse(screen.shouldShowScreen());
    }

    @Test
    public void testValidateConfirmation() {
        when(getContext().getBooleanVariable("confirm.disable.plugins")).thenReturn(true);
        assertTrue(screen.validateConfirmation());

        when(getContext().getBooleanVariable("confirm.disable.plugins")).thenReturn(false);
        assertFalse(screen.validateConfirmation());
    }

    @Test
    public void testValidateConfirmationInConsole() {
        when(getContext().isConsole()).thenReturn(true);

        when(getContext().getBooleanVariable("confirm.disable.plugins")).thenReturn(true);
        assertTrue(screen.validateConfirmation());

        verify(getContext(), never()).finish(anyInt());

        when(getContext().getBooleanVariable("confirm.disable.plugins")).thenReturn(false);
        assertFalse(screen.validateConfirmation());

        verify(getContext()).finish(1);
    }

    private void setupPluginsFolders() throws IOException {
        setupPluginsFolders("3.9.0");
    }

    private void setupPluginsFolders(String version) throws IOException {
        Properties properties = new Properties();
        properties.put("stash.home.build.version", version);
        properties.store(new FileWriter(temporaryFolder.newFile(".version")), "Test properties");

        temporaryFolder.newFolder("shared", "plugins", "installed-plugins");
        temporaryFolder.newFolder("plugins", "installed-plugins");
    }
}