# AUTOGENERATED! DO NOT EDIT! File to edit: ../../nbs/scraper/routes.ipynb.

# %% auto 0
__all__ = ['DEFAULT_LINUX_PATH', 'generate_webdriver', 'WebDriverException', 'WebDriverException_Timeout', 'wait_and_return',
           'get_pagesource', 'authenticate_domo_driver']

# %% ../../nbs/scraper/routes.ipynb 2
from selenium.webdriver.common.by import By

# %% ../../nbs/scraper/routes.ipynb 3
import os

from selenium import webdriver

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException


from bs4 import BeautifulSoup
import time

# %% ../../nbs/scraper/routes.ipynb 9
DEFAULT_LINUX_PATH = "/usr//bin/chromedriver"

# def save_cookie(driver, cookie_path = './COOKIES'):
#     deut.upsert_folder(cookie_path)

#     with open(cookie_path, 'wb') as cookie_file:
#         pickle.dump(driver.get_cookies(), cookie_file)


# def load_cookie(driver, cookie_path):

#      if not os.path.exists(cookie_path):
#          return False

#      with open(cookie_path, 'rb') as cookie_file:
#          cookies = pickle.load(cookie_file)

#          for cookie in cookies:
#              driver.add_cookie(cookie)


def generate_webdriver(
    driver_path=None,
    is_headless: bool = True,
) -> webdriver:

    options = webdriver.ChromeOptions()
    # run Selenium in headless mode

    if is_headless:
        options.add_argument("--headless")

    options.add_argument("--no-sandbox")  # needed for LINUX environments

    if driver_path:
        options.add_argument(driver_path)

    driver = webdriver.Chrome(options=options)

    return driver

# %% ../../nbs/scraper/routes.ipynb 10
class WebDriverException(Exception):
    url: str
    message: str

    def __init__(self, url, message):
        super.__init__(f"WebdriverException: {message} while retrieving {url}")


class WebDriverException_Timeout(Exception):
    def __init__(self, url, max_sleep_time):
        super().__init__(
            f"WebDriverException_Timeout: {url} did not load within {max_sleep_time} seconds."
        )


def wait_and_return(
    driver: webdriver,
    search_criteria_tuple: tuple,
    max_sleep_time=15,
    return_soup: bool = False,
):
    """
    Wait for the element to be present and return it.
    """

    try:
        ele = WebDriverWait(driver, timeout=max_sleep_time).until(
            EC.presence_of_element_located(search_criteria_tuple)
        )

        if return_soup:
            return BeautifulSoup(ele.get_attribute("outerHTML"), "lxml")
        return ele

    except TimeoutException as e:
        print(e)
        raise WebDriverException_Timeout(driver.current_url, max_sleep_time)

    except Exception as e:
        raise WebDriverException(url=driver.current_url, message=e)


def get_pagesource(
    url: str = None,
    driver: webdriver = None,
    search_criteria_tuple=None,  # for dynamically rendered pages, pass a WebDriverWait search tuple (search_element, element name)
    max_sleep_time=15,
    return_soup: bool = False,
    return_entire_page: bool = True,  # to return entire page instead of just search_criteria
    debug_prn: bool = False,
):
    """retrieve page_source, for async loaded content, can add search_criteria."""
    is_close_driver = False if driver else True

    driver = driver or generate_webdriver()

    try:
        if debug_prn:
            message = f"💤 pagesource: retrieving {url} with max sleep time {max_sleep_time} 💤"
            if search_criteria_tuple:
                message += f"using {str(search_criteria_tuple)}"

            print(message)

        if url:
            driver.get(url)

        if search_criteria_tuple:
            ele = wait_and_return(
                driver=driver,
                max_sleep_time=max_sleep_time,
                search_criteria_tuple=search_criteria_tuple,
                return_soup=return_soup,
            )

            if not return_entire_page:
                return ele

        if return_soup:
            return BeautifulSoup(driver.page_source, "lxml")

        return driver.page_source

    finally:
        if is_close_driver:
            driver.quit()

# %% ../../nbs/scraper/routes.ipynb 14
def authenticate_domo_driver(
    driver: webdriver,
    domo_instance,
    domo_username,
    domo_password,
    sleep_time=4,  # estimate of time to load pages, increase for slower internet connections
) -> webdriver:
    """returns a driver with (non sso) username and password authentication to Domo assets"""

    # authenticate against your instance
    url = f"https://{domo_instance}.domo.com/auth/index"
    driver.get(url)

    button = wait_and_return(
        driver=driver,
        search_criteria_tuple=(By.CLASS_NAME, "login-btn"),
        max_sleep_time=15,
        return_soup=False,
    )

    form_username = wait_and_return(
        driver=driver, search_criteria_tuple=(By.NAME, "username"), return_soup=False
    )

    form_password = wait_and_return(
        driver=driver, search_criteria_tuple=(By.NAME, "password"), return_soup=False
    )

    # Sending input
    form_username.clear()
    form_username.send_keys(domo_username)
    form_password.clear()
    form_password.send_keys(domo_password)
    button.click()

    time.sleep(sleep_time)

    # authenticate to domo resources
    url = f"https://domo-support.domo.com/s/"
    driver.get(url)

    domain_input = wait_and_return(
        driver=driver,
        search_criteria_tuple=(By.CLASS_NAME, "domain-input"),
        return_soup=False,
    )
    button = wait_and_return(
        driver=driver,
        search_criteria_tuple=(By.CLASS_NAME, "continue-button"),
        return_soup=False,
    )

    domain_input.send_keys(domo_instance)
    button.click()

    time.sleep(sleep_time)

    return driver
