package tests;

import core.BaseTest;
import core.Browser;
import core.BrowserArgumentProvider;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import pages.AuthoritiesPage;
import pages.InboxPage;
import pages.LoginPage;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.openqa.selenium.support.PageFactory.initElements;

/**
 * @author kote
 */
public class AuthoritiesIT extends BaseTest {

  private static final String ADMINISTRATION = "Администрирование";
  private static final String AUTHORITIES = "Безопасность действий";
  private static final String ALLOW_FOR_ROLE = "Разрешить для роли";
  private static final String BPMN_ACTION = "BPMN";
  private static final String ADMIN_ACTION = "ADMIN";
  private static final String PROCESS_INSTANCE_ACTION = "PROCESS_INSTANCE";
  private static final String LIST_ACTION = "LIST";

  private static final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(11);
  private static String generatedName;

  public AuthoritiesIT() {
    super();
  }

  @BeforeAll
  public static void beforeAll() {
    generatedName = generateName("userForAuthorities");
    String encodedPassword = passwordEncoder.encode(generatedName);
    String groupId = EXECUTION_MANAGER.insertGroupAndLinkedRole(generatedName);
    String userAccountId = EXECUTION_MANAGER.insertUser(generatedName, generatedName + "@test.ru", encodedPassword);
    EXECUTION_MANAGER.linkGroupToUser(userAccountId, groupId);
  }

  @AfterAll
  public static void afterAll() {
    EXECUTION_MANAGER.deleteUserByEmail(generatedName);
    EXECUTION_MANAGER.deleteGroupByName(generatedName);
    EXECUTION_MANAGER.deleteRoleByName(generatedName);
  }

  @ParameterizedTest
  @ArgumentsSource(BrowserArgumentProvider.class)
  public void checkPermissionsForRole(Browser browser) {
    //check action allowed for a role:
    InboxPage inboxPage = loginInAppByAdmin(browser);
    assertTrue(inboxPage.pageLoadSuccessfully());

    inboxPage.clickOnMenu(ADMINISTRATION);
    inboxPage.clickOnSubMenu(AUTHORITIES);
    AuthoritiesPage authoritiesPage = initElements(driver, AuthoritiesPage.class);
    assertTrue(authoritiesPage.pageLoadSuccessfully());

    authoritiesPage.openActionTree(BPMN_ACTION, ADMIN_ACTION, PROCESS_INSTANCE_ACTION);
    authoritiesPage.clickOnAction(LIST_ACTION);
    assertTrue(authoritiesPage.pageLoadSuccessfully());

    authoritiesPage.clickOnButton(ALLOW_FOR_ROLE);
    assertTrue(authoritiesPage.isDialogOpened(ALLOW_FOR_ROLE));

    authoritiesPage.selectRole(generatedName);
    authoritiesPage.clickOnButtonOnDialog("Разрешить");
    assertTrue(authoritiesPage.pageLoadSuccessfully());
    assertTrue(authoritiesPage.isRoleOnTheList(generatedName));

    logout(inboxPage);
    LoginPage loginPage = initElements(driver, LoginPage.class);
    assertTrue(loginPage.pageLoadSuccessfully());

    loginPage.typeLoginPasswordAndEnter(generatedName, generatedName);
    assertTrue(inboxPage.pageLoadSuccessfully());

    inboxPage.clickOnMenu(ADMINISTRATION);
    assertTrue(inboxPage.isSubMenuVisible("Экземпляры процессов"));

    //check action prohibited for a role:
    logout(inboxPage);
    reloginInAppByAdmin();
    assertTrue(inboxPage.pageLoadSuccessfully());

    inboxPage.clickOnMenu(ADMINISTRATION);
    inboxPage.clickOnSubMenu(AUTHORITIES);
    assertTrue(authoritiesPage.pageLoadSuccessfully());

    authoritiesPage.openActionTree(BPMN_ACTION, ADMIN_ACTION, PROCESS_INSTANCE_ACTION);
    authoritiesPage.clickOnAction(LIST_ACTION);
    assertTrue(authoritiesPage.pageLoadSuccessfully());

    authoritiesPage.clickOnRole(generatedName);
    authoritiesPage.clickOnButton("Запретить");
    assertTrue(authoritiesPage.isDialogOpened("Подтверждение действия"));

    authoritiesPage.clickOnButton("Да");
    assertTrue(authoritiesPage.pageLoadSuccessfully());
    assertFalse(authoritiesPage.isRoleOnTheList(generatedName));

    //todo dev WEBBPMNEXT-9095
    /*logout(inboxPage);
    assertTrue(loginPage.pageLoadSuccessfully());

    loginPage.typeLoginPasswordAndEnter(generatedName, generatedName);
    assertTrue(inboxPage.pageLoadSuccessfully());
    assertFalse(inboxPage.isMenuVisible(ADMINISTRATION));*/
  }
}