package cz.moneta.test.harness.connectors.web;

import org.openqa.selenium.Alert;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.support.ui.FluentWait;

import java.time.Duration;
import java.util.function.Consumer;

import static org.openqa.selenium.support.ui.ExpectedConditions.alertIsPresent;
import static org.openqa.selenium.support.ui.ExpectedConditions.not;

public class Alerts {

    private final SeleniumWebConnector connector;

    public Alerts(SeleniumWebConnector connector) {
        this.connector = connector;
    }

    public void dismissAlert(int timeout) {
        handleAlert(timeout, Alert::dismiss);
    }

    public void acceptAlert(int timeout) {
        handleAlert(timeout, Alert::accept);
    }

    public boolean isAlertPresent(int timeout) {
        try {
            waitForAlert(timeout);
            return true;
        } catch (TimeoutException e) {
            return false;
        }
    }

    private void handleAlert(int timeout, Consumer<Alert> action) {
        waitForAlert(timeout);
        action.accept(connector.getDriver()
                .switchTo()
                .alert());

        new FluentWait<>(connector.getDriver())
                .withTimeout(Duration.ofSeconds(timeout))
                .pollingEvery(Duration.ofMillis(300))
                .withMessage("Alert is still present after " + timeout + " seconds timeout.")
                .until(driver -> not(alertIsPresent())).apply(connector.getDriver());
    }

    public String getAlertText(int timeout) {
        waitForAlert(timeout);
        return connector.getDriver()
                .switchTo()
                .alert()
                .getText();
    }

    private void waitForAlert(int timeout) {
        new FluentWait<>(connector.getDriver())
                .withTimeout(Duration.ofSeconds(timeout))
                .pollingEvery(Duration.ofMillis(300))
                .withMessage("Alert is not present after " + timeout + " seconds timeout.")
                .until(driver -> alertIsPresent().apply(connector.getDriver()));
    }
}
