# Path: termicoder/models/Judge.py
# class Judge(ABC):
#     @abstractmethod
#     def __init__(self, session_data=None):
#         # Init should not have any network requests
#         # do them in login, logout, check_running_contest
#         self.session_data = session_data
# 
#     @abstractmethod
#     def check_login(self):
#         pass
# 
#     @abstractmethod
#     def login(self):
#         # login also controls all the messages being displayed to the user
#         pass
# 
#     @abstractmethod
#     def refresh_login(self):
#         pass
# 
#     @abstractmethod
#     def logout(self):
#         # logout also controls all the messages displayed to the user
#         pass
# 
#     @abstractmethod
#     def get_running_contests(self):
#         # return a string of running contest, do it in form of a table.
#         pass
# 
#     # This method serves both as a problem getter as well as kind of factory
#     # for problem
#     @abstractmethod
#     def get_problem(self, problem_code, contest_code):
#         # Method should call the respective Problem.__init__ method to create a
#         # problem instance and return it
#         pass
# 
#     @abstractmethod
#     def get_contest(self, contest_code):
#         # Method should call the respective Problem.__init__ method to create a
#         # contest instance with all its problems and return it
#         pass
# 
#     @abstractmethod
#     def get_problem_url(self, problem_code, contest_code):
#         # Method should return the url used by judge for a particular problem
#         pass
# 
#     @abstractmethod
#     def get_contest_url(self, contest_code):
#         # Method should return the url used by judge for a particular contest
#         pass
# 
#     @abstractmethod
#     def get_contests_list_url(self):
#         # Method should return the url used by judge for listing contest
#         pass
# 
#     @abstractmethod
#     def submit(self, problem, code_text, extension):
#         # problem is an instance of judge's problem class
#         # code test is the code to be submitted
#         # extension is the extension of the code file to determine
#         # language of submission
#         pass
# 
#     @abstractmethod
#     def get_testcase(self, inp, ans, code):
#         # returns the testcase with inp, ans and code
#         # used by termicoder test to output diff
#         pass
# 
# Path: termicoder/utils/Errors/JudgeNotFoundError.py
# class JudgeNotFoundError(Exception):
#     pass
# 
# Path: termicoder/utils/config.py
# def get_config_path(ensure_exists=False):
# def check_config_path():
# def read(rel_path, key=None, safe=False):
# def write(rel_path, key, value):
# 
# Path: termicoder/utils/logging.py



from pkg_resources import iter_entry_points
from . import Judge
from ..utils.Errors import JudgeNotFoundError
from ..utils import config
from ..utils.logging import logger
import sys
            except TypeError as e:
                # Abstract methods are not implemented
                logger.error(
                    "%s \ndoes not implement required "
                    "abstract methods of class Judge" % judge_class)
            except BaseException as e:
                logger.error(e)
                # think about something using click.abort without
                # printing traceback
                sys.exit(1)

        # sorting judges for statefulness
        self.available_judges.sort()

    def get_judge(self, judge_name):
        if(judge_name not in self.available_judges):
            raise JudgeNotFoundError
        else:
            # Return an instance of the judge
            # TODO load session data if available
            session_data = config.read('judges/sessions.yml', judge_name)
            return self._judge_classes[judge_name](session_data=session_data)

    def _write_session_data(self, judge_name):
        def decorator(function):
            def decorated_function(self_, *args, **kwargs):
                function(self_, *args, **kwargs)
                # TODO save to the appropriate location
                logger.debug("_write_session_data for %s" % judge_name)
                logger.debug(self_.session_data)

# Path: termicoder/models/Judge.py
# class Judge(ABC):
#     @abstractmethod
#     def __init__(self, session_data=None):
#         # Init should not have any network requests
#         # do them in login, logout, check_running_contest
#         self.session_data = session_data
# 
#     @abstractmethod
#     def check_login(self):
#         pass
# 
#     @abstractmethod
#     def login(self):
#         # login also controls all the messages being displayed to the user
#         pass
# 
#     @abstractmethod
#     def refresh_login(self):
#         pass
# 
#     @abstractmethod
#     def logout(self):
#         # logout also controls all the messages displayed to the user
#         pass
# 
#     @abstractmethod
#     def get_running_contests(self):
#         # return a string of running contest, do it in form of a table.
#         pass
# 
#     # This method serves both as a problem getter as well as kind of factory
#     # for problem
#     @abstractmethod
#     def get_problem(self, problem_code, contest_code):
#         # Method should call the respective Problem.__init__ method to create a
#         # problem instance and return it
#         pass
# 
#     @abstractmethod
#     def get_contest(self, contest_code):
#         # Method should call the respective Problem.__init__ method to create a
#         # contest instance with all its problems and return it
#         pass
# 
#     @abstractmethod
#     def get_problem_url(self, problem_code, contest_code):
#         # Method should return the url used by judge for a particular problem
#         pass
# 
#     @abstractmethod
#     def get_contest_url(self, contest_code):
#         # Method should return the url used by judge for a particular contest
#         pass
# 
#     @abstractmethod
#     def get_contests_list_url(self):
#         # Method should return the url used by judge for listing contest
#         pass
# 
#     @abstractmethod
#     def submit(self, problem, code_text, extension):
#         # problem is an instance of judge's problem class
#         # code test is the code to be submitted
#         # extension is the extension of the code file to determine
#         # language of submission
#         pass
# 
#     @abstractmethod
#     def get_testcase(self, inp, ans, code):
#         # returns the testcase with inp, ans and code
#         # used by termicoder test to output diff
#         pass
# 
# Path: termicoder/utils/Errors/JudgeNotFoundError.py
# class JudgeNotFoundError(Exception):
#     pass
# 
# Path: termicoder/utils/config.py
# def get_config_path(ensure_exists=False):
# def check_config_path():
# def read(rel_path, key=None, safe=False):
# def write(rel_path, key, value):
# 
# Path: termicoder/utils/logging.py



# Path: termicoder/models/JudgeFactory.py
from pkg_resources import iter_entry_points
from . import Judge
from ..utils.Errors import JudgeNotFoundError
from ..utils import config
from ..utils.logging import logger
import sys

            except TypeError as e:
                # Abstract methods are not implemented
                logger.error(
                    "%s \ndoes not implement required "
                    "abstract methods of class Judge" % judge_class)
            except BaseException as e:
                logger.error(e)
                # think about something using click.abort without
                # printing traceback
                sys.exit(1)

        # sorting judges for statefulness
        self.available_judges.sort()

    def get_judge(self, judge_name):
        if(judge_name not in self.available_judges):
            raise JudgeNotFoundError
        else:
            # Return an instance of the judge
            # TODO load session data if available
            session_data = config.read('judges/sessions.yml', judge_name)
            return self._judge_classes[judge_name](session_data=session_data)

    def _write_session_data(self, judge_name):
        def decorator(function):
            def decorated_function(self_, *args, **kwargs):
                function(self_, *args, **kwargs)
                # TODO save to the appropriate location
                logger.debug("_write_session_data for %s" % judge_name)
                logger.debug(self_.session_data)

                config.write(