package it.com.atlassian.stash;

import com.atlassian.webdriver.bitbucket.element.RevisionHistoryDialog;
import com.atlassian.webdriver.bitbucket.element.UnifiedDiffFileContent;
import com.atlassian.webdriver.bitbucket.page.FileLayoutPage;
import com.atlassian.webdriver.bitbucket.page.FileUnifiedDiffPage;
import org.junit.Test;

import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.List;
import java.util.Optional;

import static org.hamcrest.Matchers.hasSize;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;

public class ViewUnifiedDiffTest extends BaseFileContentTest {

    public static final String FILE1_AUTHOR = "Federico Silva Armas";
    public static final String FILE1_DATE = "2012-02-22T00:07:17-0600";
    public static final String FILE1_DIR = "ChangeSet";
    public static final String FILE1_NAME = "file1.txt";
    public static final String FILE1_REVISION = "b4d378388c2dc3840ff5dcf64b4ac0f1ffc17cb9";
    public static final String FILE1_REVISION_SORT = "b4d378388c2";

    @Test
    public void testUnicodePathDiff() throws Exception {
        String unicodeDir = "z\u56fd\u969b\u4ea4\u6d41\u57fa\u91d1\u6d77\u5916\u904b\u55b6\u5c02\u9580\u54e1";
        String fileName = "test.txt";
        FileUnifiedDiffPage page = loginAsAdmin(FileUnifiedDiffPage.class, getProjectKey(), getRepoSlug(), getUrlPathComponent(unicodeDir, fileName));

        assertEquals("master", page.getBranchSelector().getSelectedItemName());

        assertBreadcrumbs(page.getBreadcrumbs(), getRepoSlug(), unicodeDir, fileName);

        assertEquals("Federico Silva Armas", page.getCurrentRevisionAuthor());
        assertEquals("03fe9269cb7", page.getCurrentRevisionId());

        assertCorrectDate(page, "2012-02-05T19:04:41-0600");

        List<UnifiedDiffFileContent.Line> source = page.getFileContent().getDiffLines();
        assertThat(source, hasSize(1));
        assertLineIsAdd("hello", source.get(0));
    }

    @Test
    public void testLoadUntilRevision() {
        checkLoadUntilRevisionInTz(Optional.empty());
    }

    @Test
    public void testLoadUntilRevisionInServerTz() {
        TimeZoneTestHelper.withServerTimeZone(Optional.of(ZoneOffset.MIN), this::checkLoadUntilRevisionInTz);
        TimeZoneTestHelper.withServerTimeZone(Optional.of(ZoneOffset.MAX), this::checkLoadUntilRevisionInTz);
    }

    @Test
    public void testLoadUntilRevisionInUserTz() {
        TimeZoneTestHelper.withUserTimeZone(Optional.of(ZoneOffset.MIN), this::checkLoadUntilRevisionInTz);
        TimeZoneTestHelper.withUserTimeZone(Optional.of(ZoneOffset.MAX), this::checkLoadUntilRevisionInTz);
    }

    @Test
    public void testSwitchUntilRevision() throws Exception {
        FileLayoutPage.RevisionSpecifier revisionSpecifier = new FileLayoutPage.RevisionSpecifier(null, FILE1_REVISION);
        FileUnifiedDiffPage page = loginAsAdmin(FileUnifiedDiffPage.class, getProjectKey(), getRepoSlug(), getUrlPathComponent(FILE1_DIR, FILE1_NAME), revisionSpecifier);

        assertEquals("master", page.getBranchSelector().getSelectedItemName());

        assertBreadcrumbs(page.getBreadcrumbs(), getRepoSlug(), FILE1_DIR, FILE1_NAME);

        assertEquals(FILE1_AUTHOR, page.getCurrentRevisionAuthor());
        assertEquals(FILE1_REVISION_SORT, page.getCurrentRevisionId());
        assertEquals(FILE1_REVISION, getUntilRevisionFromUrl());

        assertCorrectDate(page, FILE1_DATE);

        List<UnifiedDiffFileContent.Line> source = page.getFileContent().getDiffLines();
        assertThat(source, hasSize(6));
        assertLineContent("Initial content - updated", source.get(0));
        assertLineContent("", source.get(1));
        assertLineContent("more updates ", source.get(2));
        assertLineContent("", source.get(3));
        assertLineIsDelete("age", source.get(4));
        assertLineIsAdd("agefwrw", source.get(5));

        RevisionHistoryDialog revisionHistoryDialog = page.getRevisionHistoryDialog();

        revisionHistoryDialog.open();
        page = page.loadUntilRevision("c4a3c85d62068dcfa1cca63c3367235facc0e301");
        page.getFileContent().waitUntilPageLoaded();

        assertEquals("master", page.getBranchSelector().getSelectedItemName());

        assertBreadcrumbs(page.getBreadcrumbs(), getRepoSlug(), FILE1_DIR, FILE1_NAME);

        assertEquals("Federico Silva Armas", page.getCurrentRevisionAuthor());
        assertEquals("c4a3c85d620", page.getCurrentRevisionId());
        assertEquals("c4a3c85d62068dcfa1cca63c3367235facc0e301", getUntilRevisionFromUrl());

        assertCorrectDate(page, "2012-02-22T01:06:08-0500");

        source = page.getFileContent().getDiffLines();
        assertThat(source, hasSize(6));
        assertLineContent("Initial content - updated", source.get(0));
        assertLineContent("", source.get(1));
        assertLineIsDelete("more updates", source.get(2));
        assertLineIsAdd("more updates ", source.get(3));
        assertLineIsAdd("", source.get(4));
        assertLineIsAdd("age", source.get(5));
    }

    @Test
    public void testContextNoExpand() throws Exception {
        FileLayoutPage.RevisionSpecifier revision = new FileLayoutPage.RevisionSpecifier(null, FILE1_REVISION);
        FileUnifiedDiffPage page = loginAsAdmin(FileUnifiedDiffPage.class, getProjectKey(), getRepoSlug(), "ChangeSet/file1.txt", revision);
        assertThat("One separator at the end", page.getFileContent().getSeparators(), hasSize(1));
    }

    private Void checkLoadUntilRevisionInTz(Optional<? extends ZoneId> zoneId) {
        FileLayoutPage.RevisionSpecifier revisionSpecifier = new FileLayoutPage.RevisionSpecifier(null, FILE1_REVISION);
        FileUnifiedDiffPage page = loginAsAdmin(FileUnifiedDiffPage.class, getProjectKey(), getRepoSlug(), getUrlPathComponent(FILE1_DIR, FILE1_NAME), revisionSpecifier);

        assertEquals("master", page.getBranchSelector().getSelectedItemName());

        assertBreadcrumbs(page.getBreadcrumbs(), getRepoSlug(), FILE1_DIR, FILE1_NAME);

        assertEquals("Federico Silva Armas", page.getCurrentRevisionAuthor());
        assertEquals("b4d378388c2", page.getCurrentRevisionId());

        assertCorrectDate(page, FILE1_DATE, zoneId);

        List<UnifiedDiffFileContent.Line> source = page.getFileContent().getDiffLines();
        assertThat(source, hasSize(6));
        assertLineContent("Initial content - updated", source.get(0));
        assertLineContent("", source.get(1));
        assertLineContent("more updates ", source.get(2));
        assertLineContent("", source.get(3));
        assertLineIsDelete("age", source.get(4));
        assertLineIsAdd("agefwrw", source.get(5));

        return null;
    }
}
