# Path: lib/Settings.py
# class Settings:
#     def __init__(self,
#                  override_settings_path='settings.cfg'):
#         self.settingsFilePath = override_settings_path
#         self.parser = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation())
#         self.settings = None
#         self.getSettings()
# 
#     def getSettings(self):
#         self.parser.read('./settings.cfg')
#         self.settings = {section: dict(**self.parser[section]) for section in self.parser.sections()}
# 
#         return self.settings
# 
#     def getServiceIp(self, service):
#         return self.settings['general']['my_ip']
# 
# Path: lib/Wrappers/Logger.py
# class Logger:
#     def __init__(self, name):
#         if 'UNITTESTING' in os.environ:
#             self.logging = NullLogger()
#         else:
#             settings = Settings().getSettings()
#             logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
#                                 level=settings["logs"]["level"])
#             self.logging = logging.getLogger(name)
# 
#     def debug(self, *args, **kwargs):
#         self.logging.debug(*args, **kwargs)
# 
#     def info(self, *args, **kwargs):
#         self.logging.info(*args, **kwargs)
# 
#     def warning(self, *args, **kwargs):
#         self.logging.warning(*args, **kwargs)
# 
#     def error(self, *args, **kwargs):
#         self.logging.error(*args, **kwargs)
# 
#     def critical(self, *args, **kwargs):
#         self.logging.critical(*args, **kwargs)
# 
#     def log(self, *args, **kwargs):
#         self.logging.log(*args, **kwargs)
# 
# Path: lib/Errors/EyeosAPIError.py
# class EyeosAPIError(Exception):
#     pass
# 
# Path: lib/EyeosApi/EyeosApiCall.py
# class EyeosApiCall:
#     """Class that wraps the requests library but adds some utility related to eyeos. For now it accepts EyeosCard
#     objects and adds them to the headers.
#     """
#     def __init__(self):
#         requests.packages.urllib3.disable_warnings()
# 
#     def __dir__(self):
#         """Override dir(), returning requests' dir()"""
#         return dir(requests)
# 
#     def __getattr__(self, item):
#         """forward all attribute or method accesses to requests"""
#         wrapped = None
#         try:
#             wrapped = getattr(requests, item)
#         except AttributeError as e:
#             raise AttributeError("'{0}' has no attribute '{1}'".format(self.__class__.__name__, item)) from e
# 
#         if not callable(wrapped):
#             # If the attribute exists but is not callable, we can't wrap it in a function, return it directly
#             return wrapped
# 
#         # Wrap the method with a function that converts the card (if present) to headers
#         @functools.wraps(wrapped)
#         def wrapper(*args, card=None, **kwargs):
#             if card:
#                 kwargs = copy.deepcopy(kwargs)
#                 if 'headers' not in kwargs:
#                     kwargs['headers'] = {}
#                 kwargs['headers'].update(card.to_headers())
# 
#             return wrapped(*args, **kwargs)
# 
#         return wrapper


from lib.Settings import Settings
from lib.Wrappers.Logger import Logger
from lib.Errors.EyeosAPIError import EyeosAPIError
from lib.EyeosApi.EyeosApiCall import EyeosApiCall
import requests


class Application:
    def __init__(self, injected_proxy_ip=None,
                 injected_api_call=None):
        self.proxy_ip = injected_proxy_ip or Settings().getServiceIp('proxy')
        self.api_call = injected_api_call or EyeosApiCall()
        self.logger = Logger(__name__)

    def insert_apps(self, apps, card):
        apps_url = "https://{0}/application/v1/applications".format(self.proxy_ip)
        self.logger.debug('POST request to: {0}'.format(apps_url))
        req = self.api_call.post(apps_url, card=card, verify=False, json=apps)

        if req.status_code != 201:
            raise EyeosAPIError("Error inserting apps. API response: [ code: {0}, content: {1}]"
                                .format(req.status_code, req.content))

        self.logger.info('Apps correctly installed.')

    def empty_apps(self, card):
        apps_url = "https://{0}/application/v1/applications".format(self.proxy_ip)
        self.logger.debug('DELETE request to: {0}'.format(apps_url))
        req = self.api_call.delete(apps_url, card=card, verify=False)

        if req.status_code != 200:

# Path: lib/Settings.py
# class Settings:
#     def __init__(self,
#                  override_settings_path='settings.cfg'):
#         self.settingsFilePath = override_settings_path
#         self.parser = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation())
#         self.settings = None
#         self.getSettings()
# 
#     def getSettings(self):
#         self.parser.read('./settings.cfg')
#         self.settings = {section: dict(**self.parser[section]) for section in self.parser.sections()}
# 
#         return self.settings
# 
#     def getServiceIp(self, service):
#         return self.settings['general']['my_ip']
# 
# Path: lib/Wrappers/Logger.py
# class Logger:
#     def __init__(self, name):
#         if 'UNITTESTING' in os.environ:
#             self.logging = NullLogger()
#         else:
#             settings = Settings().getSettings()
#             logging.basicConfig(format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
#                                 level=settings["logs"]["level"])
#             self.logging = logging.getLogger(name)
# 
#     def debug(self, *args, **kwargs):
#         self.logging.debug(*args, **kwargs)
# 
#     def info(self, *args, **kwargs):
#         self.logging.info(*args, **kwargs)
# 
#     def warning(self, *args, **kwargs):
#         self.logging.warning(*args, **kwargs)
# 
#     def error(self, *args, **kwargs):
#         self.logging.error(*args, **kwargs)
# 
#     def critical(self, *args, **kwargs):
#         self.logging.critical(*args, **kwargs)
# 
#     def log(self, *args, **kwargs):
#         self.logging.log(*args, **kwargs)
# 
# Path: lib/Errors/EyeosAPIError.py
# class EyeosAPIError(Exception):
#     pass
# 
# Path: lib/EyeosApi/EyeosApiCall.py
# class EyeosApiCall:
#     """Class that wraps the requests library but adds some utility related to eyeos. For now it accepts EyeosCard
#     objects and adds them to the headers.
#     """
#     def __init__(self):
#         requests.packages.urllib3.disable_warnings()
# 
#     def __dir__(self):
#         """Override dir(), returning requests' dir()"""
#         return dir(requests)
# 
#     def __getattr__(self, item):
#         """forward all attribute or method accesses to requests"""
#         wrapped = None
#         try:
#             wrapped = getattr(requests, item)
#         except AttributeError as e:
#             raise AttributeError("'{0}' has no attribute '{1}'".format(self.__class__.__name__, item)) from e
# 
#         if not callable(wrapped):
#             # If the attribute exists but is not callable, we can't wrap it in a function, return it directly
#             return wrapped
# 
#         # Wrap the method with a function that converts the card (if present) to headers
#         @functools.wraps(wrapped)
#         def wrapper(*args, card=None, **kwargs):
#             if card:
#                 kwargs = copy.deepcopy(kwargs)
#                 if 'headers' not in kwargs:
#                     kwargs['headers'] = {}
#                 kwargs['headers'].update(card.to_headers())
# 
#             return wrapped(*args, **kwargs)
# 
#         return wrapper


# Path: lib/EyeosApi/Application.py
from lib.Settings import Settings
from lib.Wrappers.Logger import Logger
from lib.Errors.EyeosAPIError import EyeosAPIError
from lib.EyeosApi.EyeosApiCall import EyeosApiCall
import requests



class Application:
    def __init__(self, injected_proxy_ip=None,
                 injected_api_call=None):
        self.proxy_ip = injected_proxy_ip or Settings().getServiceIp('proxy')
        self.api_call = injected_api_call or EyeosApiCall()
        self.logger = Logger(__name__)

    def insert_apps(self, apps, card):
        apps_url = "https://{0}/application/v1/applications".format(self.proxy_ip)
        self.logger.debug('POST request to: {0}'.format(apps_url))
        req = self.api_call.post(apps_url, card=card, verify=False, json=apps)

        if req.status_code != 201:
            raise EyeosAPIError("Error inserting apps. API response: [ code: {0}, content: {1}]"
                                .format(req.status_code, req.content))

        self.logger.info('Apps correctly installed.')

    def empty_apps(self, card):
        apps_url = "https://{0}/application/v1/applications".format(self.proxy_ip)
        self.logger.debug('DELETE request to: {0}'.format(apps_url))
        req = self.api_call.delete(apps_url, card=card, verify=False)

        if req.status_code != 200:

            raise EyeosAPIError("Error emptying apps. API response: [ code: {0}, content: {1}]"