package com.atlassian.stash.internal.config;

import com.atlassian.stash.internal.ApplicationConstants;
import com.google.common.collect.ImmutableSet;
import com.google.common.io.ByteSource;
import com.google.common.io.CharSource;
import com.google.common.io.CharStreams;
import com.google.common.io.InputSupplier;
import org.joda.time.DateTime;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.io.*;
import java.util.Set;

import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.when;

/**
 * ConfigurationLineProcessor + property remover/commenter test
 * See also {@link DataSourceConfigurationAmendmentTest} for more detailed DataSource tests.
 */
@RunWith(MockitoJUnitRunner.class)
public class RemovePropertiesAmendmentTest {

    private static Set<String> SETUP_PROPERTIES = ImmutableSet.of(ApplicationConstants.SETUP_LICENSE,
            ApplicationConstants.SETUP_BASE_URL, ApplicationConstants.SETUP_DISPLAY_NAME,
            ApplicationConstants.SETUP_USER_NAME, ApplicationConstants.SETUP_USER_PASSWORD,
            ApplicationConstants.SETUP_USER_DISPLAY_NAME, ApplicationConstants.SETUP_USER_EMAIL_ADDRESS
    );

    @Mock
    private Clock clock;

    @Test
    public void testWithLineProcessor() throws Exception {
        DateTime dateTime = new DateTime();
        when(clock.now()).thenReturn(dateTime);

        String unaffectedProperty = "setup.unaffected.property=some value";
        String licenseProperty = "setup.license=123456";
        String sysAdminPswProperty = "setup.sysadmin.password=adminPsw";

        final String fullFile = licenseProperty + "\n" +
                "setup.baseUrl=http://baseurl\n" +
                "setup.displayName=displayName\n" +
                "setup.sysadmin.username=admin\n" +
                sysAdminPswProperty + "\n" +
                "setup.sysadmin.displayName=Admin dispName\n" +
                "setup.sysadmin.emailAddress=fschroder@atlassian.com\n" +
                unaffectedProperty + "\n";

        CharSource inputSupplier = CharSource.wrap(fullFile);
        StringWriter stringWriter = new StringWriter();
        try (BufferedWriter bufferedWriter = new BufferedWriter(stringWriter)) {
            ConfigurationLineProcessor configurationLineProcessor = new ConfigurationLineProcessor(bufferedWriter,
                    new RemovePropertiesAmendment(clock, SETUP_PROPERTIES));
            inputSupplier.readLines(configurationLineProcessor);
        }

        String modifiedConfigFileContent = stringWriter.toString();

        assertTrue(modifiedConfigFileContent.contains(commentedProperty(ApplicationConstants.SETUP_LICENSE, clock)));
        assertTrue(modifiedConfigFileContent.contains(commentedProperty(ApplicationConstants.SETUP_BASE_URL, clock)));
        assertTrue(modifiedConfigFileContent.contains(commentedProperty(ApplicationConstants.SETUP_DISPLAY_NAME, clock)));
        assertTrue(modifiedConfigFileContent.contains(commentedProperty(ApplicationConstants.SETUP_USER_NAME, clock)));
        assertTrue(modifiedConfigFileContent.contains(commentedProperty(ApplicationConstants.SETUP_USER_PASSWORD, clock)));
        assertTrue(modifiedConfigFileContent.contains(commentedProperty(ApplicationConstants.SETUP_USER_DISPLAY_NAME, clock)));
        assertTrue(modifiedConfigFileContent.contains(commentedProperty(ApplicationConstants.SETUP_USER_EMAIL_ADDRESS, clock)));

        assertTrue(modifiedConfigFileContent.contains(unaffectedProperty));

        assertTrue(!modifiedConfigFileContent.contains(licenseProperty));
        assertTrue(!modifiedConfigFileContent.contains(sysAdminPswProperty));
    }

    private String commentedProperty(String propertyKey, Clock clock) {
        return RemovePropertiesAmendment.formatComment(propertyKey, clock);
    }
}
