package com.atlassian.stash.internal.logback;

import ch.qos.logback.core.Context;
import ch.qos.logback.core.CoreConstants;
import com.atlassian.stash.internal.logback.pattern.DefaultingMDCConverter;
import com.atlassian.stash.internal.logback.pattern.EnhancedThrowableConverter;
import com.atlassian.stash.internal.logback.pattern.RequestContextConverter;
import org.junit.Test;
import org.mockito.ArgumentCaptor;

import java.util.Map;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.Mockito.*;

public class LogFormatPropertyDefinerTest {

    @Test
    public void testGetPropertyValue() {
        assertEquals(LoggingConstants.LOG_FORMAT, new LogFormatPropertyDefiner().getPropertyValue());
    }

    @Test
    public void testSetContextCreatingMap() {
        Context context = mock(Context.class);

        new LogFormatPropertyDefiner().setContext(context);

        @SuppressWarnings("unchecked")
        ArgumentCaptor<Map<String, String>> mapCaptor = (ArgumentCaptor) ArgumentCaptor.forClass(Map.class);

        verify(context).getObject(eq(CoreConstants.PATTERN_RULE_REGISTRY));
        verify(context).putObject(eq(CoreConstants.PATTERN_RULE_REGISTRY), mapCaptor.capture());

        Map<String, String> map = mapCaptor.getValue();
        assertNotNull(map);
        assertEquals(3, map.size());
        assertEquals(DefaultingMDCConverter.class.getName(), map.get(LoggingConstants.FORMAT_DEFAULTING_MDC));
        assertEquals(RequestContextConverter.class.getName(), map.get(LoggingConstants.FORMAT_REQUEST_CONTEXT));
        assertEquals(EnhancedThrowableConverter.class.getName(), map.get(LoggingConstants.FORMAT_ENHANCED_THROWABLE));
    }

    @Test
    public void testSetContextMergingMap() {
        @SuppressWarnings("unchecked")
        Map<String, String> map = mock(Map.class);

        Context context = mock(Context.class);
        when(context.getObject(eq(CoreConstants.PATTERN_RULE_REGISTRY))).thenReturn(map);

        new LogFormatPropertyDefiner().setContext(context);

        verify(context).getObject(eq(CoreConstants.PATTERN_RULE_REGISTRY));
        verifyNoMoreInteractions(context);

        verify(map).put(eq(LoggingConstants.FORMAT_DEFAULTING_MDC), eq(DefaultingMDCConverter.class.getName()));
        verify(map).put(eq(LoggingConstants.FORMAT_REQUEST_CONTEXT), eq(RequestContextConverter.class.getName()));
        verify(map).put(eq(LoggingConstants.FORMAT_ENHANCED_THROWABLE),
                eq(EnhancedThrowableConverter.class.getName()));
        verifyNoMoreInteractions(map);
    }
}
