class Registry(object):

    _instance = None

    def __init__(self):
        self._entries = {}

    def set_context(self, context):
        """
        Store global context in registry and return it
        :param parallels.core.global_context.GlobalMigrationContext context: global migration context
        :rtype: parallels.core.global_context.GlobalMigrationContext
        """
        return self._set('context', context)

    def get_context(self):
        """
        Restore global context from registry and return it
        :rtype: parallels.core.global_context.GlobalMigrationContext
        """
        return self._get('context')

    def set_logging_configuration(self, configuration):
        """Store log configuration in registry and return it

        :type configuration: parallels.core.logging.configuration.LoggingConfiguration
        :rtype: parallels.core.logging.configuration.LoggingConfiguration
        """
        return self._set('log', configuration)

    def get_logging_configuration(self):
        """Restore log configuration from registry and return it

        :rtype: parallels.core.logging.configuration.LoggingConfiguration
        """
        return self._get('log')

    def set_workflow(self, workflow):
        """
        Store workflow in registry and return it
        :type workflow: parallels.core.workflow.base_workflow.BaseWorkflow
        :rtype: parallels.core.workflow.base_workflow.BaseWorkflow
        """
        return self._set('workflow', workflow)

    def get_workflow(self):
        """
        Restore workflow from registry and return it
        :rtype: parallels.core.workflow.base_workflow.BaseWorkflow
        """
        return self._get('workflow')

    def set_migration_lock(self, lock):
        """
        Store lock on execution of any migration command except getting progress in registry and return it
        :type lock: parallels.core.utils.file_lock.FileLock
        :rtype: parallels.core.utils.file_lock.FileLock
        """
        return self._set('migration_lock', lock)

    def get_migration_lock(self):
        """
        Restore lock on execution of any migration command except getting progress in registry and return it
        :return: parallels.core.utils.file_lock.FileLock
        """
        return self._get('migration_lock')

    def set_base_dir(self, base_dir):
        """
        Store base panel migrator directory in registry and return it
        :param str | unicode base_dir: base panel migrator directory
        :rtype: str | unicode
        """
        return self._set('base_dir', base_dir)

    def get_base_dir(self):
        """
        Restore base panel migrator directory from registry and return it
        :rtype: str
        """
        return self._get('base_dir')

    def set_var_dir(self, var_dir):
        """
        Store in registry path to directory where panel migrator will store
        variable data (configs, logs and sessions) and return it
        :param str | unicode var_dir: base panel migrator directory
        :rtype: str | unicode
        """
        return self._set('var_dir', var_dir)

    def get_var_dir(self):
        """
        Restore from registry path to directory where panel migrator will store
        variable data (configs, logs and sessions) and return it
        :rtype: str
        """
        return self._get('var_dir')

    def set_config_path(self, config_path):
        """
        Store in registry path to config used to initialize panel migrator process
        :type config_path: str
        :rtype: str
        """
        return self._set('config_path', config_path)

    def get_config_path(self):
        """
        Restore from registry path to config used to initialize panel migrator process
        :rtype: str
        """
        return self._get('config_path')

    def set_execution_path(self, execution_path):
        """
        Store in registry path to python script which initialize panel migrator process
        :type execution_path: str
        :rtype: str
        """
        return self._set('execution_path', execution_path)

    def get_execution_path(self):
        """
        Restore from registry path to python script which initialize panel migrator process
        :rtype: str
        """
        return self._get('execution_path')

    def set_command_name(self, command_name):
        """Store in registry name of the command executed by current panel migrator process

        Example: 'transfer-accounts', 'copy-content'

        :type command_name: str | unicode
        :rtype: str | unicode
        """
        return self._set('command_name', command_name)

    def get_command_name(self):
        """Restore from registry name of the command executed by current panel migrator process

        :rtype: str | unicode | None
        """
        return self._get('command_name')

    def set_execution_date(self, execution_date):
        """Store in registry date when execution of migrator started

        :type execution_date: str | unicode
        :rtype: str | unicode
        """
        return self._set('execution_date', execution_date)

    def get_execution_date(self):
        """Restore from registry date when execution of migrator started

        :rtype: str | unicode | None
        """
        return self._get('execution_date')

    def set_migration_state(self, migration_state):
        """
        :type migration_state: parallels.core.migration_state.MigrationState
        :rtype: parallels.core.migration_state.MigrationState
        """
        return self._set('migration_state', migration_state)

    def get_migration_state(self):
        """
        :rtype: parallels.core.migration_state.MigrationState
        """
        return self._get('migration_state')

    def _set(self, name, value):
        self._entries[name] = value
        return self._entries[name]

    def _get(self, name):
        return self._entries.get(name)

    @classmethod
    def get_instance(cls):
        """
        Obtain instance of registry (singleton) and return it
        :rtype: parallels.core.registry.Registry
        """
        if cls._instance is None:
            cls._instance = Registry()
        return cls._instance
