package it.com.atlassian.stash;

import com.atlassian.bitbucket.test.DefaultFuncTestData;
import com.atlassian.webdriver.bitbucket.page.FileBrowserPage;
import org.junit.Before;
import org.junit.Test;

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

public class FileBrowserTest extends QARepoFuncTest {

    private FileBrowserPage page;

    private final String TESTDIR = DefaultFuncTestData.getProject1Repository1Directory1();
    private final String TESTFILE = DefaultFuncTestData.getProject1Repository1File1();

    @Before
    public void getNewFileBrowser() {
        page = loginAsAdmin(FileBrowserPage.class, DefaultFuncTestData.getProject1(), DefaultFuncTestData.getProject1Repository1());
    }

    @Test
    public void testEnsureFileBrowserHasFiles() {
        assertThat(page.getFileRows(), hasSize(9));
    }

    @Test
    public void testFileBrowserHasItem() {
        assertTrue(page.doesHaveFile(TESTDIR));
    }

    @Test
    public void testClickDirectoryLoadsTree() {
        page = page.clickFolder(TESTDIR);
        page.doesHaveFile(TESTFILE);
    }

    @Test
    public void testEnsureParentHasNoParentDir() {
        assertFalse(page.hasParentPathInTable());
    }

    @Test
    public void testEnsureChildHasParentDir() {
        page = page.clickFolder(TESTDIR);
        assertTrue(page.hasParentPathInTable());
    }

    @Test
    public void testEnsureParentHasNoChildAfterVisitingChild() {
        page = page.clickFolder(TESTDIR);
        page.clickParentDir();
        assertFalse(page.hasParentPathInTable());
    }

    @Test
    public void testFileBrowserOpenFile() {
        FileBrowserPage page = BITBUCKET.visit(FileBrowserPage.class, DefaultFuncTestData.getProject1(), DefaultFuncTestData.getProject1Repository1(), TESTDIR);
        page.clickFile("add_file.txt");
        // If we get this far the load has been successful
    }

    @Test
    public void testKeyBoardNavigation() {
        assertFocusedFile("add_file");
        page.moveToNextFile(false);               // move to next file
        page.moveToNextFile(false);
        assertFocusedFile("binary");
        page.moveToNextFile(false);
        assertFocusedFile("branch_mod_merge");
        page.moveToPrevFile(false);               // move to previous file
        assertFocusedFile("binary");
        page.openFocusedFile("binary");           // open directory
        assertFocusedFile("B.zip");
        page.openParentDirectory("add_file");     // open parent directory
        assertFocusedFile("binary");
        page.moveToPrevFile(false);
        page.moveToPrevFile(false);
        page.openFocusedFile("add_file", "o");    // open with 'o' key
        assertFocusedFile("add_file.txt");
        page.openFocusedFile("add_file.txt");     // open text file
        assertTrue(page.getCurrentFileName().equals("add_file.txt"));
        page.openParentDirectory("add_file.txt"); // open parent directory from source view
        assertFocusedFile("add_file.txt");
    }

    @Test
    public void testFileFinder() {
        page.switchToFileFinder();
        page.findFiles("m_d");
        assertFocusedFile("moved_dir/file.txt");

        // Assert that search is still across root
        page.switchToFileBrowser();
        page.openFocusedFile("add_file");
        page.switchToFileFinder();
        page.findFiles(".zip");
        assertTrue("B.zip was not in results", page.doesHaveFile("binary/B.zip"));
        assertTrue("C.zip was not in results", page.doesHaveFile("binary/C.zip"));
        assertTrue("D.zip was not in results", page.doesHaveFile("binary/D.zip"));

        // Test file-finder keyboard navigation
        page.moveToNextFile(true);
        page.moveToNextFile(true);
        assertFocusedFile("binary/D.zip");
        page.moveToPrevFile(true);
        assertFocusedFile("binary/C.zip");
        page.openFocusedFile("C.zip");
    }

    /**
     * Verifies that directories that only contain a single subdirectory are collapsed when browsing, navigating
     * from a directory where entries are <i>not</i> collapsed to one where they are. This verifies that when the
     * data is loaded via REST it's handled correctly.
     */
    @Test
    public void testDirectoriesAreCollapsedWhenBrowsing() {
        page = loginAsAdmin(FileBrowserPage.class, QARepoFuncTest.getProjectKey(), QARepoFuncTest.getRepoSlug())
                .clickFolder("Calculator").clickFolder("src");
        assertTrue(page.doesHaveFile("main/java/org/farmas"));
        assertTrue(page.doesHaveFile("test/java/org"));

        page = page.clickFolder("main/java/org/farmas");
        assertTrue(page.doesHaveFile("Calculator.java"));
    }

    /**
     * Verifies that directories that only contain a single subdirectory are collapsed when deep linking directly
     * to a directory where one or more subdirectories should be collapsed. This verifies that when the data is
     * loaded via {@code RepositoryController} and {@code ViewFile} it's handled correctly.
     */
    @Test
    public void testDirectoriesAreCollaosedWhenDeepLinking() {
        page = loginAsAdmin(FileBrowserPage.class, QARepoFuncTest.getProjectKey(),
                QARepoFuncTest.getRepoSlug(), "/Calculator/src/main/java");
        assertTrue(page.doesHaveFile("org/farmas"));
    }

    private void assertFocusedFile(String expectedFile) {
        assertEquals(expectedFile + " should be focused", expectedFile, page.getFocusedFileName());
    }
}
