<reponame>Zadigo/zacoby
from typing import Callable

from bs4 import BeautifulSoup
from zacoby.exceptions import SelectorExistsError
from zacoby.page import browser_commands
from zacoby.page.element import DomElement
from zacoby.page.mixins import LocationMixin, ScreenShotMixin


class Location(LocationMixin, ScreenShotMixin):
    """
    A set of methods that can be used to locate or
    interract with elemnts on the HTML page

    Parameters
    ----------

        remote_connection (Type): [description]
    """
    def __init__(self, remote_connection: Callable):
        self.remote_connection = remote_connection
        self.dom_element = DomElement(remote_connection=remote_connection)

    @property
    def title(self):
        command = browser_commands.get_command('get_title')
        response = self.remote_connection._execute_command(command, requires_session_id=True)
        return response.data

    @property
    def html(self):
        pass
        # response = self._remote_connection._execute_command(
        #     browser_commands.GET_PAGE_SOURCE, session=self.session_id
        # )
        # return response.get('data')['value']

    @property
    def text(self):
        pass
        # response = self._remote_connection._execute_command(
        #     browser_commands.TEXT)
        # return response.get('data')['value']

    @property
    def window_size(self):
        pass

    @property
    def beautiful_soup(self):
        return BeautifulSoup(self.html, 'html.parser')

    def _send_command_to_remote(self, command, requires_session_id=False, **strategy):
        attrs = {
            'command': command,
            'requires_session_id': requires_session_id,
            'remote_connection': self.remote_connection,
            **strategy
        }
        response = self.remote_connection._execute_command(**attrs)
        # return response.get('data', None)
        # return response.data
        return response

    def get_element_by(self, attribute: str, name: str):
        """
        Use an attribute such as ID, CLASS or TAG to
        select an element on the page

        Parameters
        ----------

            attribute (str): ID, CLASS or TAG
            name (str): value within the attribute

        Raises
        ------

            SelectorExistsError: [description]
        """
        if attribute == 'id':
            return self.get_element_by_id(name)
        elif attribute == 'class':
            return self.get_element_by_class(name)
        elif attribute == 'tag':
            return self.get_element_by_tag_name(name)
        else:
            raise SelectorExistsError(name)

    def get_element_by_tag_name(self, name: str):
        strategy = self._build_strategy('TAG_NAME', name)
        command = browser_commands.get_command('find_element')
        response = self._send_command_to_remote(command, requires_session_id=True, **strategy)
        return self.dom_element.as_class(response, remote_connection=self.remote_connection)

    def get_element_by_id(self, name: str):
        strategy = self._build_strategy('CSS_SELECTOR', name)
        command = browser_commands.get_command('find_element')
        response = self._send_command_to_remote(command, requires_session_id=True, **strategy)
        return self.dom_element.as_class(response, remote_connection=self.remote_connection)

    def get_element_by_class(self, name: str):
        strategy = self._build_strategy('CSS_SELECTOR', name)
        command = browser_commands.get_command('find_element')
        response = self._send_command_to_remote(command, requires_session_id=True, **strategy)
        return self.dom_element.as_class(response, remote_connection=self.remote_connection)
        
    # def get_elements_by_tag_name(self, name):
    #     pass

    # def get_element_by_id(self, name):
    #     pass

    # def get_elements_by_id(self, name):
    #     pass

    # def get_element_by_class(self, name):
    #     pass

    # def get_elements_by_class(self, name):
    #     pass

    # def get_element_by_xpath(self, xpath, multiple=False):
    #     pass

    # def get_elements_by_xpath(self, xpath):
    #     pass

    # def get_element_by_link_text(self, text, multiple=False):
    #     pass

    # def get_elements_by_link_text(self, text):
    #     pass

    # def partial_link_text_match(self, text, multiple=False):
    #     pass

    # def partial_links_text_match(self, text, multiple=False):
    #     pass

    # def get_element_by_name(self, name, multiple=False):
    #     pass

    # def get_elements_by_name(self, name, multiple=False):
    #     pass

    def back(self):
        self.remote_connection._execute_command('go_back', requires_session_id=True)
        # return self._remote_connection._execute_command(
        #     browser_commands.GO_BACK, session=self.session_id
        # )

    def forward(self):
        self.remote_connection._execute_command('go_foward', requires_session_id=True)
        # return self._remote_connection._execute_command(
        #     browser_commands.GO_FOWARD, session=self.session_id
        # )

    # def refresh(self):
    #     return self._remote_connection._execute_command(
    #         browser_commands.REFRESH, session=self.session_id
    #     )

from typing import Callable

from bs4 import BeautifulSoup
from zacoby.exceptions import SelectorExistsError
from zacoby.page import browser_commands
from zacoby.page.element import DomElement
from zacoby.page.mixins import LocationMixin, ScreenShotMixin


class Location(LocationMixin, ScreenShotMixin):
    """
    A set of methods that can be used to locate or
    interract with elemnts on the HTML page

    Parameters
    ----------

        remote_connection (Type): [description]
    """
    def __init__(self, remote_connection: Callable):
        self.remote_connection = remote_connection
        self.dom_element = DomElement(remote_connection=remote_connection)

    @property
    def title(self):
        command = browser_commands.get_command('get_title')
        response = self.remote_connection._execute_command(command, requires_session_id=True)
        return response.data

    @property
    def html(self):
        pass
        # response = self._remote_connection._execute_command(
        #     browser_commands.GET_PAGE_SOURCE, session=self.session_id
        # )
        # return response.get('data')['value']

    @property
    def text(self):
        pass
        # response = self._remote_connection._execute_command(
        #     browser_commands.TEXT)
        # return response.get('data')['value']

    @property
    def window_size(self):
        pass

    @property
    def beautiful_soup(self):
        return BeautifulSoup(self.html, 'html.parser')

    def _send_command_to_remote(self, command, requires_session_id=False, **strategy):
        attrs = {
            'command': command,
            'requires_session_id': requires_session_id,
            'remote_connection': self.remote_connection,
            **strategy
        }
        response = self.remote_connection._execute_command(**attrs)
        # return response.get('data', None)
        # return response.data
        return response

    def get_element_by(self, attribute: str, name: str):
        """
        Use an attribute such as ID, CLASS or TAG to
        select an element on the page

        Parameters
        ----------

            attribute (str): ID, CLASS or TAG
            name (str): value within the attribute

        Raises
        ------

            SelectorExistsError: [description]
        """
        if attribute == 'id':
            return self.get_element_by_id(name)
        elif attribute == 'class':
            return self.get_element_by_class(name)
        elif attribute == 'tag':
            return self.get_element_by_tag_name(name)
        else:
            raise SelectorExistsError(name)

    def get_element_by_tag_name(self, name: str):
        strategy = self._build_strategy('TAG_NAME', name)
        command = browser_commands.get_command('find_element')
        response = self._send_command_to_remote(command, requires_session_id=True, **strategy)
        return self.dom_element.as_class(response, remote_connection=self.remote_connection)

    def get_element_by_id(self, name: str):
        strategy = self._build_strategy('CSS_SELECTOR', name)
        command = browser_commands.get_command('find_element')
        response = self._send_command_to_remote(command, requires_session_id=True, **strategy)
        return self.dom_element.as_class(response, remote_connection=self.remote_connection)

    def get_element_by_class(self, name: str):
        strategy = self._build_strategy('CSS_SELECTOR', name)
        command = browser_commands.get_command('find_element')
        response = self._send_command_to_remote(command, requires_session_id=True, **strategy)
        return self.dom_element.as_class(response, remote_connection=self.remote_connection)
        
    # def get_elements_by_tag_name(self, name):
    #     pass

    # def get_element_by_id(self, name):
    #     pass

    # def get_elements_by_id(self, name):
    #     pass

    # def get_element_by_class(self, name):
    #     pass

    # def get_elements_by_class(self, name):
    #     pass

    # def get_element_by_xpath(self, xpath, multiple=False):
    #     pass

    # def get_elements_by_xpath(self, xpath):
    #     pass

    # def get_element_by_link_text(self, text, multiple=False):
    #     pass

    # def get_elements_by_link_text(self, text):
    #     pass

    # def partial_link_text_match(self, text, multiple=False):
    #     pass

    # def partial_links_text_match(self, text, multiple=False):
    #     pass

    # def get_element_by_name(self, name, multiple=False):
    #     pass

    # def get_elements_by_name(self, name, multiple=False):
    #     pass

    def back(self):
        self.remote_connection._execute_command('go_back', requires_session_id=True)
        # return self._remote_connection._execute_command(
        #     browser_commands.GO_BACK, session=self.session_id
        # )

    def forward(self):
        self.remote_connection._execute_command('go_foward', requires_session_id=True)
        # return self._remote_connection._execute_command(
        #     browser_commands.GO_FOWARD, session=self.session_id
        # )

    # def refresh(self):
    #     return self._remote_connection._execute_command(
    #         browser_commands.REFRESH, session=self.session_id
    #     )
A set of methods that can be used to locate or     interract with elemnts on the HTML page      Parameters     ----------          remote_connection (Type): [description] # response = self._remote_connection._execute_command( #     browser_commands.GET_PAGE_SOURCE, session=self.session_id # ) # return response.get('data')['value'] # response = self._remote_connection._execute_command( #     browser_commands.TEXT) # return response.get('data')['value'] # return response.get('data', None) # return response.data Use an attribute such as ID, CLASS or TAG to         select an element on the page          Parameters         ----------              attribute (str): ID, CLASS or TAG             name (str): value within the attribute          Raises         ------              SelectorExistsError: [description] # def get_elements_by_tag_name(self, name): #     pass # def get_element_by_id(self, name): #     pass # def get_elements_by_id(self, name): #     pass # def get_element_by_class(self, name): #     pass # def get_elements_by_class(self, name): #     pass # def get_element_by_xpath(self, xpath, multiple=False): #     pass # def get_elements_by_xpath(self, xpath): #     pass # def get_element_by_link_text(self, text, multiple=False): #     pass # def get_elements_by_link_text(self, text): #     pass # def partial_link_text_match(self, text, multiple=False): #     pass # def partial_links_text_match(self, text, multiple=False): #     pass # def get_element_by_name(self, name, multiple=False): #     pass # def get_elements_by_name(self, name, multiple=False): #     pass # return self._remote_connection._execute_command( #     browser_commands.GO_BACK, session=self.session_id # ) # return self._remote_connection._execute_command( #     browser_commands.GO_FOWARD, session=self.session_id # ) # def refresh(self): #     return self._remote_connection._execute_command( #         browser_commands.REFRESH, session=self.session_id #     )