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

import cz.moneta.test.harness.exception.HarnessException;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.NoSuchWindowException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;
import java.util.Optional;

public class Windows {

    private final SeleniumWebConnector connector;

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

    public void switchToOtherWindow(int timeout, int expectedNumberOfWindows) {
        WebDriverWait wait = new WebDriverWait(connector.getDriver(), Duration.ofSeconds(timeout));
        wait.until(ExpectedConditions.numberOfWindowsToBe(expectedNumberOfWindows));
        connector.getDriver()
                .getWindowHandles()
                .stream()
                .filter(w -> getCurrentWindow().map(cw -> !cw.equals(w)).orElse(true))
                .findFirst()
                .map(otherWindow -> connector.getDriver().switchTo().window(otherWindow))
                .orElseThrow(() -> new HarnessException(
                        "Not possible to switch to other window. Only current window is present."));
    }

    public void switchToWindowByTitle(String title) {
        for (String winHandle : connector.getDriver().getWindowHandles()) {
            if (connector.getDriver().switchTo().window(winHandle).getTitle().equals(title)) {
                return;
            }
        }
        throw new HarnessException("A browser window named \"" + title + "\" was not found");
    }

    public void switchWindowResolution(int width, int height) {
        WebDriver.Window window = connector.getDriver().manage().window();
        Dimension targetSize = new Dimension(width, height);
        window.setSize(targetSize);
        if (!targetSize.equals(window.getSize())) {
            throw new IllegalStateException(String.format("Failed to switch window size to %d %d", width, height));
        }
    }

    private Optional<String> getCurrentWindow() {
        try {
            return Optional.of(connector
                    .getDriver()
                    .getWindowHandle());
        } catch (NoSuchWindowException e) {
            return Optional.empty();
        }
    }

    public void closeCurrentWindow() {
        connector.getDriver().close();
    }
}
