package com.atlassian.bitbucket.internal.ssh.servlet;

import com.atlassian.bitbucket.internal.ssh.fragments.SshKeysContextProvider;
import com.atlassian.bitbucket.project.Project;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.user.ApplicationUser;
import com.atlassian.bitbucket.user.TestApplicationUser;
import com.atlassian.sal.api.auth.LoginUriProvider;
import com.atlassian.webresource.api.assembler.PageBuilderService;
import com.atlassian.webresource.api.assembler.RequiredResources;
import com.google.common.collect.ImmutableMap;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Answers;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Map;

import static org.mockito.BDDMockito.given;
import static org.mockito.Matchers.anyMapOf;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class ViewKeysRequestHandlerTest {

    private static final ApplicationUser USER = new TestApplicationUser("bob");
    private static final Map<String, Object> MODEL = ImmutableMap.<String, Object>builder().build();

    @Mock
    private Repository repository;
    @Mock
    private Project project;
    @Mock
    private LoginUriProvider loginUriProvider;
    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
    private PageBuilderService pageBuilderService;
    @Mock
    private SshKeysContextProvider sshKeysContextProvider;
    @Mock
    private ResponseRenderer responseRenderer;
    @Mock
    private HttpServletRequest request;
    @Mock
    private RequiredResources requiredResources;
    @Mock
    private HttpServletResponse response;
    @InjectMocks
    private ViewKeysRequestHandler handler;

    @Before
    public void setup() {
        given(pageBuilderService.assembler().resources()).willReturn(requiredResources);
    }

    @Test(expected = ServletException.class)
    public void shouldNotSupportPost() throws Exception {
        handler.post(new SshKeysRequest(false, null, null, USER, null, null), request, response);
    }

    @Test
    public void shouldShowUserKeysForUserUrl() throws Exception {
        given(sshKeysContextProvider.createKeyTableContext(anyMapOf(String.class, Object.class), same(USER))).willReturn(MODEL);

        handler.get(new SshKeysRequest(false, null, null, USER, null, null), request, response);

        verify(requiredResources).requireContext(ViewKeysRequestHandler.CONTEXT_VIEW_SSH_KEYS);
        verify(responseRenderer).renderToResponse(request, response, SshKeysRequestHandler.MODULE_KEY, ViewKeysRequestHandler.TEMPLATE_VIEW_ACCOUNT_KEYS, MODEL);
    }

    @Test
    public void shouldShowProjectKeysForProjectUrl() throws Exception {
        given(sshKeysContextProvider.createKeyTableContext(anyMapOf(String.class, Object.class), same(project))).willReturn(MODEL);

        handler.get(new SshKeysRequest(false, project, null, null, null, null), request, response);

        verify(requiredResources).requireContext(ViewKeysRequestHandler.CONTEXT_VIEW_SSH_KEYS);
        verify(responseRenderer).renderToResponse(request, response, SshKeysRequestHandler.MODULE_KEY, ViewKeysRequestHandler.TEMPLATE_VIEW_PROJECT_KEYS, MODEL);
    }

    @Test
    public void shouldShowRepoKeysForRepoUrl() throws Exception {
        given(sshKeysContextProvider.createKeyTableContext(anyMapOf(String.class, Object.class), same(repository))).willReturn(MODEL);

        handler.get(new SshKeysRequest(false, null, repository, null, null, null), request, response);

        verify(requiredResources).requireContext(ViewKeysRequestHandler.CONTEXT_VIEW_SSH_KEYS);
        verify(responseRenderer).renderToResponse(request, response, SshKeysRequestHandler.MODULE_KEY, ViewKeysRequestHandler.TEMPLATE_VIEW_REPO_KEYS, MODEL);
    }
}
