/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache license, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the license for the specific language governing permissions and
 * limitations under the license.
 */
package org.apache.logging.log4j.server;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.nio.charset.Charset;

import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.SocketAppender;
import org.apache.logging.log4j.core.net.Protocol;
import org.apache.logging.log4j.core.net.ssl.KeyStoreConfiguration;
import org.apache.logging.log4j.core.net.ssl.SslConfiguration;
import org.apache.logging.log4j.core.net.ssl.StoreConfigurationException;
import org.apache.logging.log4j.core.net.ssl.TestConstants;
import org.apache.logging.log4j.core.net.ssl.TrustStoreConfiguration;
import org.junit.AfterClass;
import org.junit.BeforeClass;

public class SslXmlSocketServerTest extends AbstractSocketServerTest {

    private static TcpSocketServer<InputStream> server;

    private static SslConfiguration sslConfiguration;

    private static void initServerSocketFactory() throws StoreConfigurationException {
        final KeyStoreConfiguration ksc = new KeyStoreConfiguration(TestConstants.KEYSTORE_FILE,
                TestConstants.KEYSTORE_PWD(), TestConstants.KEYSTORE_TYPE, null);
        final TrustStoreConfiguration tsc = new TrustStoreConfiguration(TestConstants.TRUSTSTORE_FILE,
                TestConstants.TRUSTSTORE_PWD(), null, null);
        sslConfiguration = SslConfiguration.createSSLConfiguration(null, ksc, tsc);
    }

    @Override
    protected SocketAppender createSocketAppender(final Filter socketFilter,
            final Layout<? extends Serializable> socketLayout) {
        // @formatter:off
        return SocketAppender.newBuilder()
                .withProtocol(this.protocol)
                .withHost("localhost")
                .withPort(this.port)
                .withReconnectDelayMillis(-1)
                .withName("test")
                .withImmediateFlush(true)
                .withImmediateFail(false)
                .withIgnoreExceptions(false)
                .withLayout(socketLayout)
                .withFilter(socketFilter)
                .withSslConfiguration(sslConfiguration)
                .build();
        // @formatter:on        
    }

    @BeforeClass
    public static void setupClass() throws Exception {
        LoggerContext.getContext(false).reconfigure();
        initServerSocketFactory();
        // Use a large buffer just to test the code, the UDP test uses a tiny buffer
        server = new SecureTcpSocketServer<>(PORT_NUM, new XmlInputStreamLogEventBridge(1024 * 100,
                Charset.defaultCharset()), sslConfiguration);
        thread = server.startNewThread();
    }

    @AfterClass
    public static void tearDownClass() {
        try {
            server.shutdown();
        } catch (final IOException e) {
            e.printStackTrace();
        }
        try {
            thread.join();
        } catch (final InterruptedException e) {
            // ignore
        }
    }

    public SslXmlSocketServerTest() {
        super(Protocol.SSL, PORT, false);
    }

    @Override
    protected Layout<String> createLayout() {
        return super.createXmlLayout();
    }

}
