package it.com.atlassian.stash;

import com.atlassian.bitbucket.permission.Permission;
import com.atlassian.webdriver.bitbucket.element.PermissionRow;
import com.atlassian.webdriver.bitbucket.page.ProjectPermissionsPage;
import org.junit.Before;
import org.junit.Test;

import static com.atlassian.webdriver.bitbucket.page.ProjectPermissionsPage.AllUsersPerms;
import static java.lang.String.format;
import static org.hamcrest.Matchers.hasItem;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

public class ProjectPermissionsTest extends BaseBrowserFuncTest {
    private static final String PROJECT_KEY = "PERMS";
    private static final String PROJECT_NAME = "ProjectPermsTest";

    @Before
    public void createProject() {
        testContext.project(PROJECT_KEY, PROJECT_NAME, "Project for " + getClass().getSimpleName());
    }

    @Test
    public void testChangeToPermissionForAllUsersIsPersisted() {
        ProjectPermissionsPage projectPermsPage = loginAsAdmin(ProjectPermissionsPage.class, PROJECT_KEY);
        for (AllUsersPerms perm : AllUsersPerms.values()) {
            projectPermsPage = projectPermsPage.selectAllUsersPerms(perm);
            assertEquals("Project permission for all users was not saved", perm, projectPermsPage.getPermissionsGrantedToAllLicensedUsers());
        }
    }

    @Test
    public void testCanNotRemoveOwnAccess() throws Exception {
        testContext.projectPermission(PROJECT_KEY, "user", Permission.PROJECT_ADMIN);
        ProjectPermissionsPage projectPermsPage = loginAs("user", "user", ProjectPermissionsPage.class, PROJECT_KEY);
        final PermissionRow row = projectPermsPage.getUserItem("user").clickRemoveAndExpectError();

        assertThat(row.getErrors(), hasItem(format("You cannot revoke permission on %s as it would downgrade your own permissions.", PROJECT_NAME)));
    }

    @Test
    public void testPublicAccessDisablesNoAccess() {
        ProjectPermissionsPage projectPermsPage = loginAsAdmin(ProjectPermissionsPage.class, PROJECT_KEY);
        assertFalse(projectPermsPage.isNoAccessPermissionDisabled());
        projectPermsPage = projectPermsPage.selectAllUsersPerms(AllUsersPerms.READ)
                .setPublicAccess(true);
        assertTrue(projectPermsPage.isNoAccessPermissionDisabled());
        projectPermsPage = projectPermsPage.setPublicAccess(false);
        assertFalse(projectPermsPage.isNoAccessPermissionDisabled());
    }

    @Test
    public void testPublicAccessWhenNoAccessIsSelected() {
        ProjectPermissionsPage projectPermsPage = loginAsAdmin(ProjectPermissionsPage.class, PROJECT_KEY);
        projectPermsPage = projectPermsPage.setPublicAccess(true);
        assertTrue(projectPermsPage.isNoAccessPermissionDisabled());
        assertEquals("Project permission for all users did not default to Read", AllUsersPerms.READ,
                projectPermsPage.getPermissionsGrantedToAllLicensedUsers());
        projectPermsPage = projectPermsPage.setPublicAccess(false);
        assertFalse(projectPermsPage.isNoAccessPermissionDisabled());
        assertEquals("Project permission for all users did not revert to No Access after deselecting Public Access", AllUsersPerms.NONE,
                projectPermsPage.getPermissionsGrantedToAllLicensedUsers());
    }

    @Test
    public void testDeselectingPublicAccessAfterSelectingRead() {
        ProjectPermissionsPage projectPermsPage = loginAsAdmin(ProjectPermissionsPage.class, PROJECT_KEY);
        projectPermsPage = projectPermsPage.setPublicAccess(true)
                .selectAllUsersPerms(AllUsersPerms.READ)
                .setPublicAccess(false);
        assertEquals("Project permission for all users should remain on Read", AllUsersPerms.READ,
                projectPermsPage.getPermissionsGrantedToAllLicensedUsers());
    }
}
