package org.xbib.logging.log4j.test;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
import org.xbib.logging.MDC;
import org.xbib.logging.NDC;
import org.xbib.logging.ext.formatters.PatternFormatter;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class ThreadContextMapTest extends AbstractTest {

    public ThreadContextMapTest() {
    }

    @BeforeEach
    public void clear() {
        ThreadContext.clearAll();
        MDC.clear();
        NDC.clear();
    }

    @Test
    public void clearThreadContext() {
        final String key = "test.clear.key";
        ThreadContext.put(key, "test clear value");

        assertEquals("test clear value", ThreadContext.get(key));
        assertEquals("test clear value", MDC.get(key));

        ThreadContext.clearMap();
        assertTrue(ThreadContext.isEmpty());
        assertTrue(MDC.isEmpty());
    }

    @Test
    public void clearMdc() {
        final String key = "test.clear.key";
        ThreadContext.put(key, "test clear value");

        assertEquals("test clear value", ThreadContext.get(key));
        assertEquals("test clear value", MDC.get(key));

        MDC.clear();
        assertTrue(ThreadContext.isEmpty());
        assertTrue(MDC.isEmpty());
    }

    @Test
    public void putThreadContext() {
        final String key = "test.key";
        final TestQueueHandler handler = new TestQueueHandler(new PatternFormatter("%X{" + key + "}"));
        org.xbib.logging.Logger.getLogger("").addHandler(handler);
        ThreadContext.put(key, "test value");

        final Logger logger = LogManager.getLogger();

        logger.info("Test message");

        assertEquals("test value", handler.pollFormatted());

        ThreadContext.remove(key);

        logger.info("Test message");
        assertEquals("", handler.pollFormatted());
    }

    @Test
    public void putMdc() {
        final String key = "test.key";
        final TestQueueHandler handler = new TestQueueHandler(new PatternFormatter("%X{" + key + "}"));
        org.xbib.logging.Logger.getLogger("").addHandler(handler);
        MDC.put(key, "test value");

        final Logger logger = LogManager.getLogger();

        logger.info("Test message");

        assertEquals("test value", handler.pollFormatted());

        ThreadContext.remove(key);

        logger.info("Test message");
        assertEquals("", handler.pollFormatted());
    }

    @Test
    public void pushThreadContext() {
        final TestQueueHandler handler = new TestQueueHandler(new PatternFormatter("%x"));
        org.xbib.logging.Logger.getLogger("").addHandler(handler);

        ThreadContext.push("value-1");
        ThreadContext.push("value-2");
        ThreadContext.push("value-3");

        final Logger logger = LogManager.getLogger();

        logger.info("Test message");
        assertEquals("value-1.value-2.value-3", handler.pollFormatted());

        ThreadContext.trim(2);
        assertEquals(2, ThreadContext.getDepth());

        logger.info("Test message");
        assertEquals("value-1.value-2", handler.pollFormatted());
    }

    @Test
    public void removeThreadContext() {
        final String key = "test.clear.key";
        ThreadContext.put(key, "test clear value");

        assertEquals("test clear value", ThreadContext.get(key));
        assertEquals("test clear value", MDC.get(key));

        ThreadContext.remove(key);

        assertNull(ThreadContext.get(key));
        assertNull(MDC.get(key));
    }

    @Test
    public void removeMdc() {
        final String key = "test.clear.key";
        MDC.put(key, "test clear value");

        assertEquals("test clear value", ThreadContext.get(key));
        assertEquals("test clear value", MDC.get(key));

        MDC.remove(key);

        assertNull(ThreadContext.get(key));
        assertNull(MDC.get(key));
    }

}
