package com.atlassian.webdriver.bitbucket.page;

import com.atlassian.pageobjects.DelayedBinder;
import com.atlassian.pageobjects.binder.WaitUntil;
import com.atlassian.pageobjects.elements.query.Poller;
import com.atlassian.pageobjects.elements.query.Queries;
import com.google.common.base.Supplier;
import org.openqa.selenium.By;

import static org.hamcrest.Matchers.is;

public class BitbucketFailFastLoginPage extends BitbucketLoginPage {

    @Override
    @WaitUntil
    public void doWait() {
        // STASHDEV-6370
        // If you are already logged in, navigating to /login actually redirects you to /projects.
        // There is a subtle race condition here.  WebDriver seems to navigate to /login briefly
        // (so that in a small window of time AbstractPage.isHere() returns true), then redirects
        // you to /projects and loads the wrong page.
        // We do not want to wait for a timeout (PageBindingWaitException or NoSuchElementException)
        // during soke load tests, so here we wait for one of two conditions to become true:
        //  1) We are at /login and the "j_username" element is present, OR
        //  2) We are at /projects
        // In the latter case we finish waiting, and if the caller wasn't expecting the redirect
        // and tries to bind to BitbucketLoginPage anyway, at least we fail fast (typically with a
        // NoSuchElementException on "j_username").
        final BitbucketLoginPage loginPage = this;
        final DelayedBinder<ProjectListPage> projectListPage = pageBinder.delayedBind(ProjectListPage.class);
        Poller.waitUntil(Queries.forSupplier(timeouts, new Supplier<Boolean>() {
            public Boolean get() {
                if (isOnPage(driver, loginPage) && elementFinder.find(By.name("j_username")).isPresent()) {
                    BitbucketFailFastLoginPage.super.doWait();
                    return true;
                } else if (isOnPage(driver, projectListPage.get())) {
                    return true;    // fail fast
                } else {
                    return false;
                }
            }
        }), is(true));
    }

}
