from selenium import webdriver
from selenium.webdriver.common.action_chains import ActionChains
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import ElementNotInteractableException
from time import sleep
import os


class getDashboardScreenshot(object):
    def __init__(
        self,
        driver: webdriver,
        url: str,
        username: str,
        password: str,
        width: int = 0,
        height: int = 10000,
        path: str = os.getcwd(),
        delay: int = 1,
    ):
        super(getDashboardScreenshot, self).__init__()
        self.driver = driver
        self.action = ActionChains(driver)
        self.url = url
        self.username = username
        self.password = password
        self.width = width
        self.height = height
        self.path = self.checkPath(path)
        self.delay = delay

    def __enter__(self):
        return self

    def __exit__(self, exception_type, exception_value, traceback):
        self.driver.quit()

    @classmethod
    def createDriver(
        cls,
        url: str,
        username: str,
        password: str,
        width: int = 0,
        height: int = 0,
        type: str = 'chromium',
        path: str = os.getcwd(),
        delay: int = 1,
    ):
        if type == 'chromium':
            options = webdriver.ChromeOptions()
            options.headless = True
            driver = webdriver.Chrome(options=options)
        else:
            print(f'No supported browser {type}')
        return cls(driver, url, username, password, width, height, path, delay)

    @staticmethod
    def checkPath(path: str) -> str:
        if path[-1] != '/':
            path += '/'
        return path

    def _setWidth(self, jsProperty: str, override: int):
        script = 'return document.body.parentNode.scroll' + (jsProperty)
        return self.driver.execute_script(script) + override

    def _logIn(self):
        self.usernameElement = self.driver.find_element_by_xpath(
            '//*[@id="username"]'
        )
        self.passwordElement = self.driver.find_element_by_xpath(
            '//*[@id="password"]'
        )
        self.usernameElement.send_keys(self.username)
        self.passwordElement.send_keys(self.password)
        self.driver.find_element_by_xpath(
            '/html/body/div[2]/div/div/div[1]/form/fieldset/input[1]'
        ).click()
        sleep(2)
        return self

    def _hideElements(self):
        try:
            self.driver.find_element_by_class_name(
                'hide-global-filters'
            ).click()
        except (NoSuchElementException, ElementNotInteractableException):
            pass
        try:
            element = self.driver.find_element_by_class_name('dashboard-menu')
            self.driver.execute_script(
                "arguments[0].style.visibility = 'hidden';", element
            )
        except NoSuchElementException:
            pass
        try:
            self.action.move_to_element(
                self.driver.find_element_by_class_name('dashboard-title')
            ).perform()
            sleep(1)
        except NoSuchElementException:
            pass
        return self

    def _goToDashboard(self):
        self.driver.get(self.url)
        self.driver.implicitly_wait(10)
        self.driver.maximize_window()
        self._logIn()
        return self

    def takeScreenshot(self):
        self._goToDashboard()
        self.driver.set_window_size(
            self._setWidth('Width', self.width),
            self._setWidth('Height', self.height),
        )
        self._hideElements()
        sleep(self.delay)
        self.driver.find_element_by_class_name('dashboard-body').screenshot(
            f'{self.path}web_screenshot.png'
        )
        return self


with getDashboardScreenshot.createDriver(
    url='https://sc1uxpremn81:8000/en-US/app/wh_weekly_standup/weekly_standup_'
    'data?form.time_tok.earliest=-7d%40h&form.time_tok.latest=now&hideFilters='
    'true',
    username='admin',
    password='fWgbz6AU',
    width=1000,
    height=10000,
    delay=5,
) as screenShot:
    screenShot.takeScreenshot()
