import os
import sys

if sys.platform.startswith('win'):

    # Module multiprocessing is organized differently in Python 3.4+
    try:
        # Python 3.4+
        if sys.platform.startswith('win'):
            import multiprocessing.popen_spawn_win32 as forking
        else:
            import multiprocessing.popen_fork as forking
    except ImportError:
        import multiprocessing.forking as forking

    # First define a modified version of Popen.
    class _Popen(forking.Popen):
        def __init__(self, *args, **kw):
            if hasattr(sys, 'frozen'):
                # We have to set original _MEIPASS2 value from sys._MEIPASS
                # to get --onefile mode working.
                os.putenv('_MEIPASS2', sys._MEIPASS)
            try:
                super(_Popen, self).__init__(*args, **kw)
            finally:
                if hasattr(sys, 'frozen'):
                    # On some platforms (e.g. AIX) 'os.unsetenv()' is not
                    # available. In those cases we cannot delete the variable
                    # but only set it to the empty string. The bootloader
                    # can handle this case.
                    if hasattr(os, 'unsetenv'):
                        os.unsetenv('_MEIPASS2')
                    else:
                        os.putenv('_MEIPASS2', '')

    # Second override 'Popen' class with our modified version.
    forking.Popen = _Popen

from multiprocessing import Process, Queue, Pipe, Event, Condition, Lock


class SlaveProcess(Process):
    """ A basic simple wrapper for a multiprocessing.Process object. The constructor takes argumetns 'queues=...', 'events=...', 'conditions=...' and 'locks=...' so it's easy to add a bunch of queues/sync objects with one base class instead of creating inherited classes with specific attributes."""
    
    def __init__(self, **kwargs):
        super(SlaveProcess, self).__init__()


        self.queues = None
        if 'queues' in kwargs:
            self.queues = kwargs['queues']
        
        self.events = None
        if 'events' in kwargs:
            self.events = kwargs['events']
        
        self.locks = None
        if 'locks' in kwargs:
            self.locks = kwargs['locks']

        self.conditions = None        
        if 'conditions' in kwargs:
            self.conditions = kwargs['conditions']

        self.pipes = None
        if 'pipes' in kwargs:
            self.pipes = kwargs['pipes']



    def add_syncobject(name, obj, destination):
        dest = self.__getattr__(destination)
        if name not in dest:
            dest[name] = obj
            
            
    def add_pipe(name, pipe):
        self.add_syncobject(name, pipe, 'pipes')
            
    def add_lock(name, lock):
        self.add_syncobject(name, lock, 'locks')

    def add_event(name, event):
        self.add_syncobject(name, event, 'events')

    def add_condition(name, condition):
        self.add_syncobject(name, condition, 'conditions')

    def add_queue(name, queue):
        self.add_syncobject(name, queue, 'queues')
    
        
