# Path: FabLabKasse/libs/process_helper/nonblockingProcess.py
# class nonblockingProcess(object):
# 
#     """non-blocking subprocess, based on asyncproc"""
# 
#     def __init__(self, cmd, env=None):
#         self.process = asyncproc.Process(cmd, stderr=file("/dev/null", "w"),
#                                          env=env or {})
#         self._read_buffer = ""
# 
#     def write(self, string):
#         self.process.write(string)
# 
#     def readline(self):
#         """read line from process stdout, if available, else return None"""
#         # hasLine() implicitly reads new data
#         if not self.hasLine():
#             return None
# 
#         # return line without trailing \n
#         end = self._read_buffer.find("\n")
#         line = self._read_buffer[0:end]
#         # remove line from buffer
#         self._read_buffer = self._read_buffer[end + 2:]
#         return line
# 
#     def hasLine(self):
#         self._read_buffer += self.process.read()
#         return "\n" in self._read_buffer
# 
#     def isAlive(self):
#         return (self.process.wait(os.WNOHANG) == None)


import sys
import logging
import pickle
import base64
import monotonic as monotonic_time
from FabLabKasse.libs.process_helper.nonblockingProcess import nonblockingProcess

"""
Client for accessing a cash device driver.
"""



class PaymentDeviceClient(object):

    """
    Client for accessing a cash device driver. It starts a new python process
    ("server") for the specified device driver. It uses non-blocking
    communication and talks to the server process using stdin/stdout.
    """

    def __init__(self, cmd, options):
        """
        :param cmd: class name of the device driver
        :param options: dictionary of options (name (required), device, ...)
                        that were set in config.ini as deviceN_foo=value
        :type options: dict(unicode, unicode)
        """
        self.stopped = False
        self.canAccept_cachedResponse = None
        self._reset()
        self.waitingForResponse = False
        if (sys.version_info.major, sys.version_info.minor) != (2, 7):
            raise Exception("not running in python2.7 - please update PaymentDeviceClient to use the right python version for the payment servers")
        args = ["/usr/bin/env", "python2.7", "-m", "FabLabKasse.cashPayment.server." + cmd, base64.b64encode(pickle.dumps(options))]
        logging.info("starting cashPayment server: PYTHONPATH=.. " + " ".join(args))

# Path: FabLabKasse/libs/process_helper/nonblockingProcess.py
# class nonblockingProcess(object):
# 
#     """non-blocking subprocess, based on asyncproc"""
# 
#     def __init__(self, cmd, env=None):
#         self.process = asyncproc.Process(cmd, stderr=file("/dev/null", "w"),
#                                          env=env or {})
#         self._read_buffer = ""
# 
#     def write(self, string):
#         self.process.write(string)
# 
#     def readline(self):
#         """read line from process stdout, if available, else return None"""
#         # hasLine() implicitly reads new data
#         if not self.hasLine():
#             return None
# 
#         # return line without trailing \n
#         end = self._read_buffer.find("\n")
#         line = self._read_buffer[0:end]
#         # remove line from buffer
#         self._read_buffer = self._read_buffer[end + 2:]
#         return line
# 
#     def hasLine(self):
#         self._read_buffer += self.process.read()
#         return "\n" in self._read_buffer
# 
#     def isAlive(self):
#         return (self.process.wait(os.WNOHANG) == None)


# Path: FabLabKasse/cashPayment/client/PaymentDeviceClient.py
import sys
import logging
import pickle
import base64
import monotonic as monotonic_time
from FabLabKasse.libs.process_helper.nonblockingProcess import nonblockingProcess


"""
Client for accessing a cash device driver.
"""



class PaymentDeviceClient(object):

    """
    Client for accessing a cash device driver. It starts a new python process
    ("server") for the specified device driver. It uses non-blocking
    communication and talks to the server process using stdin/stdout.
    """

    def __init__(self, cmd, options):
        """
        :param cmd: class name of the device driver
        :param options: dictionary of options (name (required), device, ...)
                        that were set in config.ini as deviceN_foo=value
        :type options: dict(unicode, unicode)
        """
        self.stopped = False
        self.canAccept_cachedResponse = None
        self._reset()
        self.waitingForResponse = False
        if (sys.version_info.major, sys.version_info.minor) != (2, 7):
            raise Exception("not running in python2.7 - please update PaymentDeviceClient to use the right python version for the payment servers")
        args = ["/usr/bin/env", "python2.7", "-m", "FabLabKasse.cashPayment.server." + cmd, base64.b64encode(pickle.dumps(options))]
        logging.info("starting cashPayment server: PYTHONPATH=.. " + " ".join(args))

        self.process = nonblockingProcess(args, {"PYTHONPATH": ".."})