package old;

import old.core.BaseTest;
import old.core.Browser;

import org.junit.jupiter.api.AfterEach;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import old.page.InboxPage;
import old.page.LoginPage;
import old.page.ProcessesPage;

import old.util.ExecutionManager;
import old.util.PropertyManager;

import java.io.IOException;
import java.util.Properties;

import static org.junit.jupiter.api.Assertions.assertTrue;
import static old.page.BaseComponentPage.getLoginHeaderBy;
import static old.page.BaseComponentPage.getProgressBar;
import static old.util.DataUtil.BASE_PART_FOR_USER;

/**
 * @author gulnaz
 */
public abstract class BaseComponentIT extends BaseTest {

  protected static final String ACCESS_LEVEL_ID = "a6bf4b31-6648-4095-b269-2a950b548a10";
  protected static final String ORGANIZATION_ID = "3516544f-64c5-4883-9047-28bcce74d1be";
  protected static final String SECURITY_ADMIN_GROUP_ID = "84c5c1e2-081e-45e1-a874-d6bb232e57ad";
  protected static final String BPMN_ADMIN_GROUP_ID = "ddfdc772-7aee-492f-be7d-7e95ea2f45b3";
  protected static final String BPMN_USER_GROUP_ID = "62cd890b-99f7-47a8-be60-e330186b17a0";
  protected static final String BPMN_SUPERUSER_GROUP_ID = "273d8bbd-0e82-4064-a548-850e9aa61756";

  protected static ExecutionManager EXECUTION_MANAGER = new ExecutionManager();

  protected InboxPage inboxPage;
  protected ProcessesPage processPage;
  protected String login;
  protected String password;
  protected String name;
  private Properties config;
  final Logger logger = LoggerFactory.getLogger(getClass());


  BaseComponentIT() {
    super();
    initCredentialsConfig();
    initCredentials();
  }

  @AfterEach
  public void exit() {
    if (processPage != null) {
      assertTrue(processPage.thereIsNoError());
    }
  }

  public void openBrowserAndLoginForAdmin(Browser browser) {
    initDriver(browser);
    initDemoCredentials();
    login(login, password);
  }

  public void openBrowserAndLoginForJbpm(Browser browser) {
    initDriver(browser);
    initQaAdminCredentials();
    login(login, password);
  }

  private void initCredentialsConfig() {
    try {
      config = PropertyManager.getProperties();
    }
    catch (IOException e) {
      throw new RuntimeException("Failed to get properties. " + e);
    }
  }

  protected void initCredentials() {
    login = config.getProperty("login");
    password = config.getProperty("password");
  }

  protected void initDemoCredentials() {
    login = config.getProperty("demo_login");
    password = config.getProperty("demo_password");
  }

  protected void initQaAdminCredentials() {
    login = config.getProperty("qa_admin_login");
    password = config.getProperty("qa_admin_password");
  }

  void login(String login, String password) {
    WebDriverWait wait = getExplicitWait(getDefaultTimeout());
    wait.until(ExpectedConditions.invisibilityOfElementLocated(getProgressBar()));
    wait.until(ExpectedConditions.visibilityOfElementLocated(getLoginHeaderBy()));
    LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);

    try {
      inboxPage = loginPage.login(login, password);
    }
    catch (TimeoutException e) {
      throw new RuntimeException("Failed to login", e);
    }
  }

  void initAdminName() {
    initName(BASE_PART_FOR_USER);
  }

  void initName(String basePart) {
    String random = String.valueOf(20000 + (int) (Math.random() * 20000));
    name = basePart + "-" + random;
    logger.info(name + " record has been initialized");
  }

  protected boolean isElementEnabled (String xpath){
    return driver.findElement(By.xpath(String.format(xpath))).isEnabled();
  }

  protected LoginPage getLoginPage() {
    return PageFactory.initElements(driver, LoginPage.class);
  }

  public void openBrowserAndLogin(Browser browser) {
    initDriver(browser);
    login(login, password);
  }

  protected InboxPage getInboxPage() {
    return PageFactory.initElements(driver, InboxPage.class);
  }
}