package com.atlassian.stash.internal.scm.git.protocol.http;

import com.atlassian.bitbucket.project.Project;
import com.atlassian.event.api.EventPublisher;
import com.atlassian.bitbucket.event.repository.RepositoryEvent;
import com.atlassian.bitbucket.i18n.I18nService;
import com.atlassian.bitbucket.repository.Repository;
import com.atlassian.bitbucket.request.RequestContext;
import com.atlassian.bitbucket.scm.CommandExitHandler;
import com.atlassian.bitbucket.scm.CommandInputHandler;
import com.atlassian.bitbucket.scm.CommandOutputHandler;
import com.atlassian.bitbucket.scm.git.command.GitCommand;
import com.atlassian.bitbucket.scm.git.command.GitCommandBuilderFactory;
import com.atlassian.bitbucket.scm.git.command.GitScmCommandBuilder;
import com.atlassian.bitbucket.scm.git.GitScmConfig;
import org.junit.Before;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.util.Collections;

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.*;

public abstract class GitSmartRequestTestBase {

    @Mock
    protected GitCommandBuilderFactory builderFactory;
    @Mock
    protected GitCommand command;
    @Mock
    protected GitScmConfig config;
    @Mock
    protected EventPublisher eventPublisher;
    @Mock
    protected I18nService i18nService;
    @Mock
    protected Project project;
    @Mock
    protected Repository repository;
    @Mock
    protected HttpServletRequest request;
    @Mock
    protected RequestContext requestContext;
    @Mock
    protected HttpServletResponse response;
    @Mock
    protected ServletContext servletContext;
    protected GitSmartRequest smartRequest;

    @Before
    public void setUp() throws Exception {
        when(config.getRepositoryDir(any(Repository.class))).thenReturn(mock(File.class));

        when(request.getHeaderNames()).thenReturn(Collections.enumeration(Collections.emptySet()));
        when(request.getPathInfo()).thenReturn("/stuff/projectKey/repoSlug");
        when(repository.getProject()).thenReturn(project);

        smartRequest = createGitSmartRequest();
    }

    protected abstract GitSmartRequest createGitSmartRequest();

    protected static RepositoryEvent onSuccessCaptureEvent(EventPublisher eventPublisher, GitSmartRequest request) {
        request.onSuccess();
        ArgumentCaptor<RepositoryEvent> captor = ArgumentCaptor.forClass(RepositoryEvent.class);
        verify(eventPublisher).publish(captor.capture());
        return captor.getValue();
    }

    @SuppressWarnings("unchecked")
    protected void stubCommandBuilder() {
        GitScmCommandBuilder commandBuilder = mock(GitScmCommandBuilder.class);
        when(builderFactory.builder(any(Repository.class))).thenReturn(commandBuilder);
        when(commandBuilder.command(any(String.class))).thenReturn(commandBuilder);
        when(commandBuilder.exitHandler(any(CommandExitHandler.class))).thenReturn(commandBuilder);
        when(commandBuilder.inputHandler(any(CommandInputHandler.class))).thenReturn(commandBuilder);
        when(commandBuilder.withEnvironment(any(String.class), any(String.class))).thenReturn(commandBuilder);
        when(commandBuilder.build(any(CommandOutputHandler.class))).thenReturn(command);
    }
}