package io.dropwizard.jetty;

import io.dropwizard.jackson.DiscoverableSubtypeResolver;

import java.security.KeyStore;
import java.security.KeyStoreException;
import java.util.Collection;
import java.util.Set;

import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;

import org.apache.commons.lang3.SystemUtils;
import org.junit.Test;

import com.google.common.base.Function;
import com.google.common.collect.Collections2;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;

public class HttpsConnectorFactoryTest {
    private static final String WINDOWS_MY_KEYSTORE_NAME = "Windows-MY";
    private final Validator validator = Validation.buildDefaultValidatorFactory().getValidator();

    @Test
    public void isDiscoverable() throws Exception {
        assertThat(new DiscoverableSubtypeResolver().getDiscoveredSubtypes())
                .contains(HttpsConnectorFactory.class);
    }

    @Test
    public void nonWindowsKeyStoreValidation() throws Exception {
        HttpsConnectorFactory factory = new HttpsConnectorFactory();
        Collection<String> properties = getViolationProperties(validator.validate(factory));
        assertThat(properties.contains("validKeyStorePassword")).isEqualTo(true);
        assertThat(properties.contains("validKeyStorePath")).isEqualTo(true);
    }

    @Test
    public void windowsKeyStoreValidation() throws Exception {
        HttpsConnectorFactory factory = new HttpsConnectorFactory();
        factory.setKeyStoreType(WINDOWS_MY_KEYSTORE_NAME);
        Collection<String> properties = getViolationProperties(validator.validate(factory));
        assertThat(properties.contains("validKeyStorePassword")).isEqualTo(false);
        assertThat(properties.contains("validKeyStorePath")).isEqualTo(false);
    }

    @Test
    public void windowsKeyStore() throws Exception {
        HttpsConnectorFactory factory = new HttpsConnectorFactory();
        factory.setKeyStoreType(WINDOWS_MY_KEYSTORE_NAME);
        if (canAccessWindowsKeyStore()) {
            factory.buildSslContextFactory();
            return;
        } else {
            try {
                factory.buildSslContextFactory();
                fail("Windows key store should not be supported here");
            } catch (IllegalStateException ex) {
                assertThat(ex.getMessage()).containsIgnoringCase("not supported");
            }
        }
    }

    private boolean canAccessWindowsKeyStore() {
        if (SystemUtils.IS_OS_WINDOWS) {
            try {
                KeyStore.getInstance(WINDOWS_MY_KEYSTORE_NAME);
                return true;
            } catch (KeyStoreException e) {
                return false;
            }
        }
        return false;
    }

    private <T> Collection<String> getViolationProperties(Set<ConstraintViolation<T>> violations) {
        return Collections2.transform(violations, new Function<ConstraintViolation<T>, String>() {
            @Override
            public String apply(ConstraintViolation<T> input) {
                return input.getPropertyPath().toString();
            }
        });
    }
}

@@ -178,24 +178,47 @@
 Collection;%0A
+import java.util.List;%0A
 import java.
@@ -227,16 +227,16 @@
 il.Set;%0A
-
 %0Aimport 
@@ -390,16 +390,69 @@
 mUtils;%0A
+import org.eclipse.jetty.util.ssl.SslContextFactory;%0A
 import o
@@ -553,16 +553,64 @@
 ctions2;
+%0Aimport com.google.common.collect.ImmutableList;
 %0A%0Aimport
@@ -1052,16 +1052,16 @@
 ypes())%0A
-
         
@@ -1107,32 +1107,1101 @@
 .class);%0A    %7D%0A%0A
+    @Test%0A    public void testSupportedProtocols() %7B%0A    %09List%3CString%3E supportedProtocols = ImmutableList.of(%22SSLv3%22, %22TLS1%22);%0A%0A    %09HttpsConnectorFactory factory = new HttpsConnectorFactory();%0A    %09factory.setKeyStorePassword(%22password%22); // necessary to avoid a prompt for a password%0A    %09factory.setSupportedProtocols(supportedProtocols);%0A%0A    %09SslContextFactory sslContextFactory = factory.buildSslContextFactory();%0A    %09assertThat(ImmutableList.copyOf(sslContextFactory.getIncludeProtocols())).isEqualTo(supportedProtocols);%0A    %7D%0A%0A    @Test%0A    public void testExcludedProtocols() %7B%0A    %09List%3CString%3E excludedProtocols = ImmutableList.of(%22SSLv3%22, %22TLS1%22);%0A%0A    %09HttpsConnectorFactory factory = new HttpsConnectorFactory();%0A    %09factory.setKeyStorePassword(%22password%22); // necessary to avoid a prompt for a password%0A    %09factory.setExcludedProtocols(excludedProtocols);%0A%0A    %09SslContextFactory sslContextFactory = factory.buildSslContextFactory();%0A    %09assertThat(ImmutableList.copyOf(sslContextFactory.getExcludeProtocols())).isEqualTo(excludedProtocols);%0A    %7D%0A%0A
     @Test%0A    pu

Add unit tests for supported/excluded HTTPS protocols