package com.atlassian.stash.internal.johnson;

import com.atlassian.johnson.DefaultJohnsonEventContainer;
import com.atlassian.johnson.JohnsonEventContainer;
import com.atlassian.johnson.event.Event;
import com.atlassian.johnson.event.EventLevel;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import javax.servlet.http.HttpServletRequest;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.junit.Assert.*;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class JohnsonUtilsTest {

    private JohnsonEventContainer eventContainer = new DefaultJohnsonEventContainer();

    private Event maintenanceEvent = new Event(null, null, new EventLevel(JohnsonUtils.LEVEL_MAINTENANCE, null));
    private Event errorEvent = new Event(null, null, new EventLevel(EventLevel.ERROR, null));

    @Mock
    private HttpServletRequest request;

    @Test
    public void testGetRedirectUrl() throws Exception {
        when(request.getParameter("next")).thenReturn("/test/relative/url");
        assertThat("next URL shows up in redirect",
                JohnsonUtils.getRedirectUrl(request, "/this/should/not/be/shown"),
                equalTo("/test/relative/url"));
    }

    @Test
    public void testGetRedirectUrlWithNoNext() throws Exception {
        when(request.getParameter("next")).thenReturn(null);
        assertThat("fallback URL shows up in redirect",
                JohnsonUtils.getRedirectUrl(request, "/fallback-url"),
                equalTo("/fallback-url"));
    }

    @Test
    public void testFindHighestEventLevel() throws Exception {
        assertNull(JohnsonUtils.findHighestEventLevel(eventContainer));

        eventContainer.addEvent(errorEvent);
        assertEquals(EventLevel.ERROR, JohnsonUtils.findHighestEventLevel(eventContainer));

        eventContainer.addEvent(maintenanceEvent);
        assertEquals(EventLevel.ERROR, JohnsonUtils.findHighestEventLevel(eventContainer));

        eventContainer.removeEvent(errorEvent);
        assertEquals(JohnsonUtils.LEVEL_MAINTENANCE, JohnsonUtils.findHighestEventLevel(eventContainer));
    }

    @Test
    public void testHasEventAtLeastAtLevel() throws Exception {
        assertFalse(JohnsonUtils.isLevelAtLeast(JohnsonUtils.LEVEL_MAINTENANCE, EventLevel.ERROR));
        assertTrue(JohnsonUtils.isLevelAtLeast(EventLevel.ERROR, EventLevel.ERROR));
        assertTrue(JohnsonUtils.isLevelAtLeast(EventLevel.FATAL, EventLevel.ERROR));
    }

    @Test
    public void testHasEventAtMostAtLevel() throws Exception {
        assertTrue(JohnsonUtils.isLevelAtMost(JohnsonUtils.LEVEL_MAINTENANCE, EventLevel.ERROR));
        assertTrue(JohnsonUtils.isLevelAtMost(EventLevel.ERROR, EventLevel.ERROR));
        assertFalse(JohnsonUtils.isLevelAtMost(EventLevel.FATAL, EventLevel.ERROR));
    }
}