package org.apache.qpid.tests.http.endtoend.port;

import static java.nio.charset.StandardCharsets.UTF_8;
import static javax.servlet.http.HttpServletResponse.SC_CREATED;
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static org.apache.qpid.test.utils.TestSSLConstants.JAVA_KEYSTORE_TYPE;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeThat;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.time.Duration;
import java.time.Instant;
import java.time.temporal.ChronoUnit;
import java.util.Base64;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import javax.jms.Connection;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
import javax.jms.MessageProducer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.NamingException;

import com.fasterxml.jackson.core.type.TypeReference;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import org.apache.qpid.server.model.ConfiguredObject;
import org.apache.qpid.server.model.Port;
import org.apache.qpid.server.model.Protocol;
import org.apache.qpid.server.model.Transport;
import org.apache.qpid.server.security.NonJavaKeyStore;
import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager;
import org.apache.qpid.server.transport.network.security.ssl.SSLUtil;
import org.apache.qpid.server.util.DataUrlUtils;
import org.apache.qpid.systests.ConnectionBuilder;
import org.apache.qpid.tests.http.HttpTestBase;
import org.apache.qpid.tests.http.HttpTestHelper;

public class PortTest extends HttpTestBase
{
    private static final String PASS = "changeit";
    private static final String QUEUE_NAME = "testQueue";
    private static final TypeReference<Boolean> BOOLEAN = new TypeReference<Boolean>()
    {
    };
    private String _portName;
    private String _authenticationProvider;
    private String _keyStoreName;
    private Set<File> _storeFiles;
    private File _storeFile;

    @Before
    public void setUp() throws Exception
    {
        assumeThat(SSLUtil.canGenerateCerts(), is(true));

        _portName = getTestName();
        _authenticationProvider = _portName + "AuthenticationProvider";
        _keyStoreName = _portName + "KeyStore";
        createAnonymousAuthenticationProvider();
        final SSLUtil.KeyCertPair keyCertPair = createKeyStore(_keyStoreName);
        final X509Certificate certificate = keyCertPair.getCertificate();

        _storeFiles = new HashSet<>();
        _storeFile = createTrustStore(certificate);

        getBrokerAdmin().createQueue(QUEUE_NAME);
    }


    @After
    public void tearDown()
    {
        _storeFiles.forEach(f -> assertTrue(f.delete()));
    }

    @Test
    public void testSwapKeyStoreAndUpdateTlsOnAmqpPort() throws Exception
    {
        final int port = createPort(Transport.SSL);
        final Connection connection = createConnection(port, _storeFile.getAbsolutePath());
        try
        {
            final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            final MessageProducer producer = session.createProducer(session.createQueue(QUEUE_NAME));
            producer.send(session.createTextMessage("A"));

            final SSLUtil.KeyCertPair keyCertPair = createKeyStoreAndUpdatePortTLS();
            final File storeFile = createTrustStore(keyCertPair.getCertificate());
            final Connection connection2 = createConnection(port, storeFile.getAbsolutePath());
            try
            {
                producer.send(session.createTextMessage("B"));

                final Session session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
                final MessageConsumer consumer = session2.createConsumer(session2.createQueue(QUEUE_NAME));
                connection2.start();

                assertMessage(consumer.receive(getReceiveTimeout()), "A");
                assertMessage(consumer.receive(getReceiveTimeout()), "B");
            }
            finally
            {
                connection2.close();
            }
        }
        finally
        {
            connection.close();
        }
    }

    @Test
    public void testUpdateKeyStoreAndUpdateTlsOnAmqpPort() throws Exception
    {
        final int port = createPort(Transport.SSL);
        final Connection connection = createConnection(port, _storeFile.getAbsolutePath());
        try
        {
            final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            final MessageProducer producer = session.createProducer(session.createQueue(QUEUE_NAME));
            producer.send(session.createTextMessage("A"));

            final SSLUtil.KeyCertPair keyCertPair = updateKeyStoreAndUpdatePortTLS();
            final File storeFile = createTrustStore(keyCertPair.getCertificate());
            final Connection connection2 = createConnection(port, storeFile.getAbsolutePath());
            try
            {
                producer.send(session.createTextMessage("B"));

                final Session session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
                final MessageConsumer consumer = session2.createConsumer(session2.createQueue(QUEUE_NAME));
                connection2.start();

                assertMessage(consumer.receive(getReceiveTimeout()), "A");
                assertMessage(consumer.receive(getReceiveTimeout()), "B");
            }
            finally
            {
                connection2.close();
            }
        }
        finally
        {
            connection.close();
        }
    }

    @Test
    public void testSwapKeyStoreAndUpdateTlsOnWssPort() throws Exception
    {
        assumeThat(getProtocol(), is(equalTo(Protocol.AMQP_1_0)));
        final int port = createPort(Transport.WSS);
        final Connection connection = createConnectionBuilder(port, _storeFile.getAbsolutePath())
                .setTransport("amqpws").build();
        try
        {
            final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            final MessageProducer producer = session.createProducer(session.createQueue(QUEUE_NAME));
            producer.send(session.createTextMessage("A"));

            final SSLUtil.KeyCertPair keyCertPair = createKeyStoreAndUpdatePortTLS();
            final File storeFile = createTrustStore(keyCertPair.getCertificate());
            final Connection connection2 = createConnectionBuilder(port, storeFile.getAbsolutePath())
                    .setTransport("amqpws").build();
            try
            {
                producer.send(session.createTextMessage("B"));

                final Session session2 = connection2.createSession(false, Session.AUTO_ACKNOWLEDGE);
                final MessageConsumer consumer = session2.createConsumer(session2.createQueue(QUEUE_NAME));
                connection2.start();

                assertMessage(consumer.receive(getReceiveTimeout()), "A");
                assertMessage(consumer.receive(getReceiveTimeout()), "B");
            }
            finally
            {
                connection2.close();
            }
        }
        finally
        {
            connection.close();
        }
    }

    @Test
    public void testSwapKeyStoreAndUpdateTlsOnHttpPort() throws Exception
    {
        final int port = createHttpPort();

        HttpTestHelper helper = new HttpTestHelper(getBrokerAdmin(), null, port);
        helper.setTls(true);
        helper.setKeyStore(_storeFile.getAbsolutePath(), PASS);

        final Map<String, Object> attributes = getHelper().getJsonAsMap("port/" + _portName);
        final Map<String, Object> ownAttributes = helper.getJsonAsMap("port/" + _portName);
        assertEquals(attributes, ownAttributes);

        final SSLUtil.KeyCertPair keyCertPair = createKeyStoreAndUpdatePortTLS();
        final File storeFile = createTrustStore(keyCertPair.getCertificate());
        helper.setKeyStore(storeFile.getAbsolutePath(), PASS);

        final Map<String, Object> attributes2 = getHelper().getJsonAsMap("port/" + _portName);
        final Map<String, Object> ownAttributes2 = helper.getJsonAsMap("port/" + _portName);
        assertEquals(attributes2, ownAttributes2);
    }

    private void createAnonymousAuthenticationProvider() throws IOException
    {
        final Map<String, Object> data = Collections.singletonMap(ConfiguredObject.TYPE,
                                                                  AnonymousAuthenticationManager.PROVIDER_TYPE);
        getHelper().submitRequest("authenticationprovider/" + _authenticationProvider, "PUT", data, SC_CREATED);
    }

    private SSLUtil.KeyCertPair createKeyStore(final String keyStoreName) throws Exception
    {
        return submitKeyStoreAttributes(keyStoreName, SC_CREATED);
    }

    private SSLUtil.KeyCertPair submitKeyStoreAttributes(final String keyStoreName, final int status) throws Exception
    {
        final SSLUtil.KeyCertPair keyCertPair = generateSelfSignedCertificate();

        final Map<String, Object> attributes = new HashMap<>();
        attributes.put(NonJavaKeyStore.NAME, keyStoreName);
        attributes.put(NonJavaKeyStore.PRIVATE_KEY_URL,
                       DataUrlUtils.getDataUrlForBytes(toPEM(keyCertPair.getPrivateKey()).getBytes(UTF_8)));
        attributes.put(NonJavaKeyStore.CERTIFICATE_URL,
                       DataUrlUtils.getDataUrlForBytes(toPEM(keyCertPair.getCertificate()).getBytes(UTF_8)));
        attributes.put(NonJavaKeyStore.TYPE, "NonJavaKeyStore");

        getHelper().submitRequest("keystore/" + keyStoreName, "PUT", attributes, status);
        return keyCertPair;
    }

    private ConnectionBuilder createConnectionBuilder(final int port, final String absolutePath)
    {
        return getConnectionBuilder().setPort(port)
                                     .setTls(true)
                                     .setVerifyHostName(false)
                                     .setTrustStoreLocation(absolutePath)
                                     .setTrustStorePassword(PASS);
    }

    private Connection createConnection(final int port, final String absolutePath)
            throws NamingException, JMSException
    {
        return createConnectionBuilder(port, absolutePath).build();
    }

    private int createPort(final Transport transport) throws IOException
    {
        return createPort("AMQP",  transport);
    }

    private int createHttpPort() throws IOException
    {
        return createPort("HTTP",  Transport.SSL);
    }

    private int createPort(final String type, final Transport transport) throws IOException
    {
        final Map<String, Object> port = new HashMap<>();
        port.put(Port.NAME, _portName);
        port.put(Port.AUTHENTICATION_PROVIDER, _authenticationProvider);
        port.put(Port.TYPE, type);
        port.put(Port.PORT, 0);
        port.put(Port.KEY_STORE, _keyStoreName);
        port.put(Port.TRANSPORTS, Collections.singleton(transport));

        getHelper().submitRequest("port/" + _portName, "PUT", port, SC_CREATED);

        return getBoundPort();
    }

    private int getBoundPort() throws IOException
    {
        final Map<String, Object> attributes = getHelper().getJsonAsMap("port/" + _portName);
        assertTrue(attributes.containsKey("boundPort"));
        assertTrue(attributes.get("boundPort") instanceof Number);

        return ((Number) attributes.get("boundPort")).intValue();
    }

    private File createTrustStore(final X509Certificate certificate)
            throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException
    {
        final java.security.KeyStore ks = java.security.KeyStore.getInstance(JAVA_KEYSTORE_TYPE);
        ks.load(null);
        ks.setCertificateEntry("certificate", certificate);
        final File storeFile = File.createTempFile(getTestName(), ".pkcs12");
        try (FileOutputStream fos = new FileOutputStream(storeFile))
        {
            ks.store(fos, PASS.toCharArray());
        }
        finally
        {
            _storeFiles.add(storeFile);
        }
        return storeFile;
    }

    private SSLUtil.KeyCertPair generateSelfSignedCertificate() throws Exception
    {
        return SSLUtil.generateSelfSignedCertificate("RSA",
                                                     "SHA256WithRSA",
                                                     2048,
                                                     Instant.now()
                                                            .minus(1, ChronoUnit.DAYS)
                                                            .toEpochMilli(),
                                                     Duration.of(365, ChronoUnit.DAYS)
                                                             .getSeconds(),
                                                     "CN=foo",
                                                     Collections.emptySet(),
                                                     Collections.emptySet());
    }

    private String toPEM(final Certificate pub) throws CertificateEncodingException
    {
        return toPEM(pub.getEncoded(), "-----BEGIN CERTIFICATE-----", "-----END CERTIFICATE-----");
    }

    private String toPEM(final PrivateKey key)
    {
        return toPEM(key.getEncoded(), "-----BEGIN PRIVATE KEY-----", "-----END PRIVATE KEY-----");
    }

    private String toPEM(final byte[] bytes, final String header, final String footer)
    {
        StringBuilder pem = new StringBuilder();
        pem.append(header).append("\n");
        String base64encoded = Base64.getEncoder().encodeToString(bytes);
        while (base64encoded.length() > 76)
        {
            pem.append(base64encoded, 0, 76).append("\n");
            base64encoded = base64encoded.substring(76);
        }
        pem.append(base64encoded).append("\n");
        pem.append(footer).append("\n");
        return pem.toString();
    }

    private void assertMessage(final Message messageA, final String a) throws JMSException
    {
        assertThat(messageA, is(notNullValue()));
        assertThat(messageA, is(instanceOf(TextMessage.class)));
        assertThat(((TextMessage) messageA).getText(), is(equalTo(a)));
    }

    private SSLUtil.KeyCertPair createKeyStoreAndUpdatePortTLS() throws Exception
    {
        final SSLUtil.KeyCertPair keyCertPair = createKeyStore(_keyStoreName + "_2");
        final Map<String, Object> data = Collections.singletonMap(Port.KEY_STORE, _keyStoreName + "_2");
        getHelper().submitRequest("port/" + _portName, "POST", data, SC_OK);
        final boolean response = getHelper().postJson("port/" + _portName + "/updateTLS",
                                                      Collections.emptyMap(),
                                                      BOOLEAN,
                                                      SC_OK);
        assertTrue(response);

        return keyCertPair;
    }

    private SSLUtil.KeyCertPair updateKeyStoreAndUpdatePortTLS() throws Exception
    {
        final SSLUtil.KeyCertPair keyCertPair = submitKeyStoreAttributes(_keyStoreName, SC_OK);
        final boolean response = getHelper().postJson("port/" + _portName + "/updateTLS",
                                                      Collections.emptyMap(),
                                                      BOOLEAN,
                                                      SC_OK);
        assertTrue(response);

        return keyCertPair;
    }
}
