package com.atlassian.stash.internal.web.admin;

import com.atlassian.bitbucket.cluster.ClusterService;
import com.atlassian.bitbucket.i18n.I18nService;
import com.atlassian.stash.internal.jdbc.DataSourceConfiguration;
import com.atlassian.stash.internal.migration.MigrationService;
import com.atlassian.bitbucket.mockito.MockitoUtils;
import com.atlassian.bitbucket.nav.NavBuilder;
import com.google.common.collect.Maps;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpSession;
import java.util.Map;

import static com.atlassian.stash.internal.web.admin.DbConfigurationController.KEY_LAST_MIGRATION_SUCCESSFUL;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.not;
import static org.hamcrest.collection.IsMapContaining.hasKey;
import static org.junit.Assert.*;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class DbConfigurationControllerTest {

    @Mock(answer = Answers.RETURNS_MOCKS)
    private I18nService i18nService;
    @Mock
    private ClusterService clusterService;
    @Mock
    private DataSourceConfiguration dataSourceConfiguration;
    @Mock
    private MigrationService migrationService;
    @Mock
    private NavBuilder navBuilder;
    @Mock
    private HttpSession session;

    private Map<String, Object> sessionAttributes;

    private DbConfigurationController controller;

    @Before
    public void setup() throws Exception {
        sessionAttributes = Maps.newHashMap();
        when(session.getAttribute(anyString())).thenAnswer(MockitoUtils.returnsValueFromMap(sessionAttributes));
        doAnswer(MockitoUtils.putsValueInMap(sessionAttributes)).when(session).setAttribute(anyString(), any());
        doAnswer(MockitoUtils.removesValueInMap(sessionAttributes)).when(session).removeAttribute(anyString());

        when(dataSourceConfiguration.getDriverClassName()).thenReturn("org.h2.Driver");

        controller = new DbConfigurationController(i18nService, clusterService, dataSourceConfiguration, migrationService, navBuilder);
    }

    @Test
    public void testViewDbConfig() throws Exception {
        ModelAndView modelAndView = controller.viewDbConfig(session);
        assertNotNull(modelAndView);
        assertEquals(DbConfigurationController.VIEW_DB_CONFIG_PAGE, modelAndView.getViewName());
        assertThat(modelAndView.getModel(), allOf(hasKey("jdbcUrl"), hasKey("jdbcUsername"), hasKey("isJdbcPasswordSet")));
    }

    @Test
    public void testViewDbConfigAfterSuccessfulMigration() throws Exception {
        sessionAttributes.put(DbConfigurationController.ATTR_LAST_MIGRATION_STATUS, Boolean.TRUE);
        ModelAndView modelAndView = controller.viewDbConfig(session);
        assertNotNull(modelAndView);
        assertEquals(DbConfigurationController.VIEW_DB_CONFIG_PAGE, modelAndView.getViewName());
        Map<String, Object> model = modelAndView.getModel();
        assertNotNull(model);
        assertEquals(Boolean.TRUE, model.get(KEY_LAST_MIGRATION_SUCCESSFUL));
        assertThat(sessionAttributes, not(hasKey(KEY_LAST_MIGRATION_SUCCESSFUL)));
    }
}
