package it.com.atlassian.stash;

import com.atlassian.bitbucket.test.RepositoryTestHelper;
import com.atlassian.webdriver.bitbucket.element.RepositoryTable;
import com.atlassian.webdriver.bitbucket.page.EmptyRepositoryPage;
import com.atlassian.webdriver.bitbucket.page.ProjectOverviewPage;
import com.atlassian.webdriver.bitbucket.page.RepositoryCreatePage;
import org.junit.BeforeClass;
import org.junit.Test;

import java.util.Collection;

import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;

public class RepositoryCreateTest extends BaseBrowserFuncTest {
    private static final String PROJECT_NAME = "Func test project";
    // Use MVC to test rewrite rules don't break forwarding
    private static final String PROJECT_KEY = "MVC";
    private static final String PROJECT_DESC = "Func test project description";

    @BeforeClass
    public static void createProject() {
        getClassTestContext().project(PROJECT_KEY, PROJECT_NAME, PROJECT_DESC);
    }

    @Test
    public void testCreateCancellation() throws Exception {
        ProjectOverviewPage overviewPage = loginAsAdmin(ProjectOverviewPage.class, PROJECT_KEY);

        // check that the func-test plugin's CancelableEventTestingListener cancels the creation of the repository
        RepositoryCreatePage errorPage = overviewPage.clickCreateRepository()
                .setName("cancelme")
                .submitFail();

        // Verify why the creation was canceled and that the cancellation message from the plugin is shown
        Collection<String> errorMessages = errorPage.getAuiErrorMessages();
        assertThat(errorMessages, hasSize(1));
        assertThat(errorMessages, contains(endsWith("\nTesting repository creation cancellation.")));
    }

    @Test
    public void testCreateRepositoryFromProjectPage() throws Exception {
        ProjectOverviewPage overviewPage = loginAsAdmin(ProjectOverviewPage.class, PROJECT_KEY);

        assertTrue("Should be able to create a repository", overviewPage.canCreateRepository());

        String slug = "test-repo";
        try {
            EmptyRepositoryPage emptyRepositoryPage = overviewPage.clickCreateRepository()
                    .setName(slug)
                    .submitSuccess();
            assertFalse(emptyRepositoryPage.getItems().hasCommitsItem());

            overviewPage = BITBUCKET.visit(ProjectOverviewPage.class, PROJECT_KEY);
            RepositoryTable.RepositoryRow repositoryRow = overviewPage.getRepositoryTable().findRepositoryByName("test-repo");
            assertNotNull("Repository should exist on project overview page", repositoryRow);
        } finally {
            RepositoryTestHelper.deleteRepositoryAndWait(PROJECT_KEY, slug);
        }
    }

    @Test
    public void testCancelCreateRepository() throws Exception {
        // Create a repository
        String slug = "test-repo";
        ProjectOverviewPage projectOverviewPage = loginAsAdmin(RepositoryCreatePage.class, PROJECT_KEY)
                .setName(slug)
                .cancel();

        RepositoryTable repositoryTable = projectOverviewPage.getRepositoryTable();
        assertFalse("There should be no repository table since repository should not have been created", repositoryTable.isPresent());
    }
    
    @Test
    public void testCreateRepositoryErrors() throws Exception {
        // Create a repository
        String slug = "test-repo";
        testContext.repository(PROJECT_KEY, slug);

        RepositoryCreatePage createRepoPage = loginAsAdmin(RepositoryCreatePage.class, PROJECT_KEY)
                .setName(slug)
                .submitFail();

        assertThat(createRepoPage.getFieldsWithErrors(), not(empty()));
        assertThat(createRepoPage.getFieldsWithErrors(), contains("name"));

        createRepoPage = createRepoPage.setName("   ")
                        .submitFail();

        assertThat(createRepoPage.getFieldsWithErrors(), not(empty()));
        assertThat(createRepoPage.getFieldsWithErrors(), contains("name"));

        createRepoPage = createRepoPage.setName("&1234")
                        .submitFail();

        assertThat(createRepoPage.getFieldsWithErrors(), not(empty()));
        assertThat(createRepoPage.getFieldsWithErrors(), contains("name"));

        createRepoPage = createRepoPage.setName("!@$)(*)U%!")
                        .submitFail();

        assertThat(createRepoPage.getFieldsWithErrors(), not(empty()));
        assertThat(createRepoPage.getFieldsWithErrors(), contains("name"));
    }
}
