# Path: src/singleton/singleton_factory.py
# class SingletonFactory(object):
#     """
#     A factory of the same instances of injected classes.
#     """
# 
#     # a mapping between the name of a class and the instance.
#     __mappings = {}
# 
#     @staticmethod
#     def build(class_, **constructor_args):
#         """
#         Builds an instance of the given class pointer together with the provided constructor arguments.
#         Returns the SAME instance for a given class.
#         
#         :param class_: A pointer to the definition of the class. 
#         :param constructor_args: The arguments for the class instance.
#         :return: An instance of the provided class.
#         """
# 
#         # if the class instance is mapped, then retrieve it.
#         if str(class_) in SingletonFactory.__mappings:
#             instance_ = SingletonFactory.__mappings[str(class_)]
# 
#         # else create the instance and map it to the class name.
#         else:
#             instance_ = class_(**constructor_args)
#             SingletonFactory.__mappings[str(class_)] = instance_
# 
#         return instance_


from typing import Union
from selenium.webdriver import Chrome, Firefox
from selenium.webdriver import Remote
from src.singleton.singleton_factory import SingletonFactory
import psutil
"""
Different project related utilities like Selenium driver connection
"""



def get_appium_driver(url, desired_capabilities) -> Remote:
    """
    Return the same instance to the Appium driver.

    :param url: the URL (address and port) where the service runs.
    :param desired_capabilities: session configuration data.
    :return: returns the SAME instance of the driver
    """
    return SingletonFactory.build(Remote,
                                  command_executor=url,
                                  desired_capabilities=desired_capabilities)


def get_selenium_driver(browser_name: str) -> Union[Chrome, Firefox]:
    """
    Return the same instance to the Selenium driver.

    :param browser_name: the name of the browser: chrome or mozilla
    :type browser_name: str
    :return: an instance of the required driver.
    :rtype: Union[Chrome, Mozilla]
    """
    if browser_name.upper() == 'CHROME':

# Path: src/singleton/singleton_factory.py
# class SingletonFactory(object):
#     """
#     A factory of the same instances of injected classes.
#     """
# 
#     # a mapping between the name of a class and the instance.
#     __mappings = {}
# 
#     @staticmethod
#     def build(class_, **constructor_args):
#         """
#         Builds an instance of the given class pointer together with the provided constructor arguments.
#         Returns the SAME instance for a given class.
#         
#         :param class_: A pointer to the definition of the class. 
#         :param constructor_args: The arguments for the class instance.
#         :return: An instance of the provided class.
#         """
# 
#         # if the class instance is mapped, then retrieve it.
#         if str(class_) in SingletonFactory.__mappings:
#             instance_ = SingletonFactory.__mappings[str(class_)]
# 
#         # else create the instance and map it to the class name.
#         else:
#             instance_ = class_(**constructor_args)
#             SingletonFactory.__mappings[str(class_)] = instance_
# 
#         return instance_


# Path: src/utils.py
from typing import Union
from selenium.webdriver import Chrome, Firefox
from selenium.webdriver import Remote
from src.singleton.singleton_factory import SingletonFactory
import psutil

"""
Different project related utilities like Selenium driver connection
"""



def get_appium_driver(url, desired_capabilities) -> Remote:
    """
    Return the same instance to the Appium driver.

    :param url: the URL (address and port) where the service runs.
    :param desired_capabilities: session configuration data.
    :return: returns the SAME instance of the driver
    """
    return SingletonFactory.build(Remote,
                                  command_executor=url,
                                  desired_capabilities=desired_capabilities)


def get_selenium_driver(browser_name: str) -> Union[Chrome, Firefox]:
    """
    Return the same instance to the Selenium driver.

    :param browser_name: the name of the browser: chrome or mozilla
    :type browser_name: str
    :return: an instance of the required driver.
    :rtype: Union[Chrome, Mozilla]
    """
    if browser_name.upper() == 'CHROME':

        return SingletonFactory.build(Chrome)