# -----------------------------------------------------------------------
# Window Wait Conditions
#
# These are a collection of classes for WebDriverWait specific to Windows
#
# ------------------------------------------------------------------------

from accelarobotkeywords.config.seleniumsettings import SeleniumSettings
import time
from robot.api import logger


class WindowSwitchToWindowWithTitle(object):
    """An expected condition to wait for a window with a specified title then switch to it"""
    def __init__(self, title):
        self.title = title

    def __call__(self, driver):
        try:
            driver.implicitly_wait(1)
            handles = driver.window_handles
            for handle in handles:
                driver.switch_to.window(handle)
                window_title = driver.title
                if window_title.casefold() == self.title.casefold():
                    return True
            # above actions do not invoke the implicit wait, so sleep instead
            time.sleep(1)
            return False
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())


class WindowSwitchToWindowWithUrl(object):
    """An expected condition to wait for a window with a specified url then switch to it"""
    def __init__(self, url):
        self.url = url

    def __call__(self, driver):
        try:
            driver.implicitly_wait(1)
            handles = driver.window_handles
            for handle in handles:
                driver.switch_to.window(handle)
                window_url = driver.current_url
                if self.url in window_url:
                    return True
            # above actions do not invoke the implicit wait, so sleep instead
            time.sleep(1)
            return False
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())


class WindowSwitchToWindowWithHandleIndex(object):
    """switches to window based on the handle index passed on"""
    def __init__(self, handle_index):
        self.index = handle_index
        logger.info(handle_index)

    def __call__(self, driver):
        try:
            driver.implicitly_wait(1)
            handles = driver.window_handles
            if len(handles) > 1:
                driver.switch_to.window(handles[int(self.index)])
                return True
            # above actions do not invoke the implicit wait, so sleep instead
            time.sleep(1)
            return False
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())


class WindowSwitchToFirstFoundWindow(object):
    """An expected condition to wait for a second window and switch to it"""
    def __init__(self, default_handle):
        self.default_handle = default_handle

    def __call__(self, driver):
        try:
            driver.implicitly_wait(1)
            handles = driver.window_handles
            for handle in handles:
                if handle != self.default_handle:
                    driver.switch_to.window(handle)
                    return True
            # above actions dont invoke an implicit wait
            time.sleep(1)
            return False
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())


class WindowMaximizeWindow(object):
    """Maximize the window"""
    def __call__(self, driver):
        try:
            driver.maximize_window()
            time.sleep(1)
            return True
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())


class WindowTitleShouldMatch(object):
    """An expected condition to match window title with passed in title, title can be partially match """
    def __init__(self, title):
        self.title = title

    def __call__(self, driver):
        try:
            driver.implicitly_wait(1)
            window_title = driver.title
            if window_title.casefold() in self.title.casefold() or self.title.casefold() in window_title.casefold():
                return True
            # above actions do not invoke the implicit wait, so sleep instead
            time.sleep(1)
            return False
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())


class WindowTitleShouldBeEqual(object):
    """An expected condition to match window title with passed in title, title has to be exact match """
    def __init__(self, title):
        self.title = title

    def __call__(self, driver):
        try:
            driver.implicitly_wait(1)
            window_title = driver.title
            if window_title.casefold() == self.title.casefold():
                return True
            # above actions do not invoke the implicit wait, so sleep instead
            time.sleep(1)
            return False
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())


class WindowCloseWindowBasedOnTitle(object):
    """An expected condition to close window based on title, title can be partially match """
    def __init__(self, title):
        self.title = title

    def __call__(self, driver):
        try:
            driver.implicitly_wait(1)
            window_title = driver.title
            if window_title.casefold() in self.title.casefold() or self.title.casefold() in window_title.casefold():
                driver.close()
                return True
            # above actions do not invoke the implicit wait, so sleep instead
            time.sleep(1)
            return False
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())


class WindowCloseWindowBasedOnTitleEqual(object):
    """An expected condition to close window based on title, title has to be exact match """
    def __init__(self, title):
        self.title = title

    def __call__(self, driver):
        try:
            driver.implicitly_wait(1)
            window_title = driver.title
            if window_title.casefold() == self.title.casefold():
                driver.close()
                return True
            # above actions do not invoke the implicit wait, so sleep instead
            time.sleep(1)
            return False
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())


class WindowCloseWindowBasedOnUrl(object):
    """An expected condition to close window based on url, url can be partially match """
    def __init__(self, url):
        self.url = url

    def __call__(self, driver):
        try:
            driver.implicitly_wait(1)
            window_url = driver.current_url
            if window_url in self.url or self.url in window_url:
                driver.close()
                return True
            # above actions do not invoke the implicit wait, so sleep instead
            time.sleep(1)
            return False
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())


class WindowSwitchToMainWindow(object):
    """An expected condition to switch to main/base window, window that is opened first at the beginning of test"""
    def __init__(self, default_handle):
        self.default_handle = default_handle

    def __call__(self, driver):
        try:
            driver.implicitly_wait(1)
            handles = driver.window_handles
            for handle in handles:
                if handle == self.default_handle:
                    driver.switch_to.window(handle)
                    return True
            # above actions dont invoke an implicit wait
            time.sleep(1)
            return False
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())

class WindowSwitchToNewWindow(object):
    """
    An expected condition to open a new window or tab.
    """
    def __init__(self, window_type):
        self.window_type = window_type

    def __call__(self, driver):
        try:
            driver.implicitly_wait(1)
            # switch to a new window or tab
            driver.switch_to.new_window(self.window_type)
            return True
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())
            
class WindowGetWindowTitle(object):
    """Gets the title of a window - returns the title text in a string"""
    def __call__(self, driver):
        try:
            driver.implicitly_wait(1)
            window_title = driver.title
            return window_title.strip()
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())

class WindowGetWindowHandles(object):
    """Gets the number of windows that are open - returns the total count"""
    def __call__(self, driver):
        try:
            driver.implicitly_wait(1)
            handles = driver.window_handles
            total_windows = len(handles)
            return int(total_windows)
        except Exception:
            return False
        finally:
            driver.implicitly_wait(SeleniumSettings.get_implicit_wait())
