/*
 * 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 static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.IOException;
import java.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.appender.AppenderLoggingException;
import org.apache.logging.log4j.core.appender.ConsoleAppender;
import org.apache.logging.log4j.core.appender.SocketAppender;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.logging.log4j.core.layout.SerializedLayout;
import org.apache.logging.log4j.core.net.Protocol;
import org.apache.logging.log4j.jackson.json.layout.JsonLayout;
import org.apache.logging.log4j.jackson.xml.layout.XmlLayout;
import org.apache.logging.log4j.test.AvailablePortFinder;
import org.apache.logging.log4j.test.appender.ListAppender;
import org.junit.After;
import org.junit.Ignore;
import org.junit.Test;

/**
 *
 */
public abstract class AbstractSocketServerTest {

    protected static Thread thread;

    private static final String MESSAGE = "This is test message";

    private static final String MESSAGE_2 = "This is test message 2";

    private static final String MESSAGE_WITH_SPECIAL_CHARS = "{This}\n[is]\"n\"a\"\r\ntrue:\n\ttest,\nmessage";

    static final int PORT_NUM = AvailablePortFinder.getNextAvailable();

    static final int PORT = PORT_NUM;

    private final LoggerContext ctx = LoggerContext.getContext(false);

    private final boolean expectLengthException;

    protected final int port;

    protected final Protocol protocol;

    private final Logger rootLogger = ctx.getLogger(AbstractSocketServerTest.class.getSimpleName());

    protected AbstractSocketServerTest(final Protocol protocol, final int port, final boolean expectLengthException) {
        this.protocol = protocol;
        this.port = port;
        this.expectLengthException = expectLengthException;
    }

    protected Layout<String> createJsonLayout() {
        // @formatter: off
        return JsonLayout.newBuilder()
            .setLocationInfo(true)
            .setProperties(true)
            .setPropertiesAsList(false)
            .setComplete(false)
            .setCompact(false)
            .setEventEol(false)
            .setIncludeStacktrace(true)
            .build();
        // @formatter: on

        //return JsonLayout.createLayout(null, true, true, false, false, false, false, null, null, null, true);
    }

    protected abstract Layout<? extends Serializable> createLayout();

    protected Layout<? extends Serializable> createSerializedLayout() {
        return SerializedLayout.createLayout();
    }

    protected Layout<String> createXmlLayout() {
        return XmlLayout.newBuilder()
                .setLocationInfo(true)
                .setProperties(true)
                .setComplete(false)
                .setCompact(false)
                .setIncludeStacktrace(true)
                .build();
    }

    @After
    public void tearDown() {
        final Map<String, Appender> map = rootLogger.getAppenders();
        for (final Map.Entry<String, Appender> entry : map.entrySet()) {
            final Appender appender = entry.getValue();
            rootLogger.removeAppender(appender);
            appender.stop();
        }
    }

    @Test
    @Ignore("Broken test?")
    public void test1000ShortMessages() throws Exception {
        testServer(1000);
    }

    @Test
    @Ignore("Broken test?")
    public void test100ShortMessages() throws Exception {
        testServer(100);
    }

    @Test
    public void test10ShortMessages() throws Exception {
        testServer(10);
    }

    @Test
    public void test1ShortMessages() throws Exception {
        testServer(1);
    }

    @Test
    public void test2ShortMessages() throws Exception {
        testServer(2);
    }

    @Test
    public void test64KBMessages() throws Exception {
        final char[] a64K = new char[1024 * 64];
        Arrays.fill(a64K, 'a');
        final String m1 = new String(a64K);
        final String m2 = MESSAGE_2 + m1;
        if (expectLengthException) {
            try {
                testServer(m1, m2);
            } catch (final AppenderLoggingException are) {
                assertTrue("", are.getCause() != null && are.getCause() instanceof IOException);
                // Failure expected.
            }
        } else {
            testServer(m1, m2);
        }
    }


    @Test
    public void testMessagesWithSpecialChars() throws Exception {
        testServer(MESSAGE_WITH_SPECIAL_CHARS);
    }


    private void testServer(final int size) throws Exception {
        final String[] messages = new String[size];
        for (int i = 0; i < messages.length; i++) {
            messages[i] = MESSAGE + " " + i;
        }
        testServer(messages);
    }

    protected void testServer(final String... messages) throws Exception {
        final Filter socketFilter = new ThreadNameFilter(Filter.Result.NEUTRAL, Filter.Result.DENY);
        final Filter serverFilter = new ThreadNameFilter(Filter.Result.DENY, Filter.Result.NEUTRAL);
        final Layout<? extends Serializable> socketLayout = createLayout();
        final SocketAppender socketAppender = createSocketAppender(socketFilter, socketLayout);
        socketAppender.start();
        final ListAppender listAppender = new ListAppender("Events", serverFilter, null, false, false);
        listAppender.start();
        final PatternLayout layout = PatternLayout.newBuilder().withPattern("%m %ex%n").build();
        final ConsoleAppender console = ConsoleAppender.createDefaultAppenderForLayout(layout);
        final Logger serverLogger = ctx.getLogger(this.getClass().getName());
        serverLogger.addAppender(console);
        serverLogger.setAdditive(false);

        // set appender on root and set level to debug
        rootLogger.addAppender(socketAppender);
        rootLogger.addAppender(listAppender);
        rootLogger.setAdditive(false);
        rootLogger.setLevel(Level.DEBUG);
        for (final String message : messages) {
            rootLogger.debug(message);
        }
        final int MAX_TRIES = 400;
        for (int i = 0; i < MAX_TRIES; i++) {
            if (listAppender.getEvents().size() < messages.length) {
                try {
                    // Let the server-side read the messages.
                    Thread.sleep(50);
                } catch (final Exception e) {
                    e.printStackTrace();
                }
            } else {
                break;
            }
        }
        final List<LogEvent> events = listAppender.getEvents();
        assertNotNull("No event retrieved", events);
        assertEquals("Incorrect number of events received", messages.length, events.size());
        for (int i = 0; i < messages.length; i++) {
            assertTrue("Incorrect event", events.get(i).getMessage().getFormattedMessage().equals(messages[i]));
        }
    }

    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)
                .build();
        // @formatter:on        
    }

}
