# -*- generated by 1.0.6 -*-
import da
PatternExpr_189 = da.pat.TuplePattern([da.pat.ConstantPattern('request'), da.pat.FreePattern('c2'), da.pat.FreePattern('p')])
PatternExpr_214 = da.pat.TuplePattern([da.pat.ConstantPattern('release'), da.pat.BoundPattern('_BoundPattern217_'), da.pat.BoundPattern('_BoundPattern218_')])
PatternExpr_247 = da.pat.TuplePattern([da.pat.ConstantPattern('ack'), da.pat.BoundPattern('_BoundPattern250_'), da.pat.BoundPattern('_BoundPattern251_')])
PatternExpr_279 = da.pat.TuplePattern([da.pat.ConstantPattern('request'), da.pat.FreePattern('c'), da.pat.FreePattern('p')])
PatternExpr_330 = da.pat.TuplePattern([da.pat.ConstantPattern('done'), da.pat.BoundPattern('_BoundPattern333_')])
PatternExpr_336 = da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.FreePattern(None)]), da.pat.TuplePattern([da.pat.ConstantPattern('done'), da.pat.BoundPattern('_BoundPattern346_')])])
PatternExpr_221 = da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.FreePattern(None)]), da.pat.TuplePattern([da.pat.ConstantPattern('release'), da.pat.BoundPattern('_BoundPattern231_'), da.pat.BoundPattern('_BoundPattern232_')])])
PatternExpr_254 = da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.FreePattern(None)]), da.pat.TuplePattern([da.pat.ConstantPattern('ack'), da.pat.BoundPattern('_BoundPattern264_'), da.pat.BoundPattern('_BoundPattern265_')])])
_config_object = {'channel': 'fifo', 'clock': 'Lamport'}
import sys

class P(da.DistProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._PReceivedEvent_0 = []
        self._PReceivedEvent_1 = []
        self._PReceivedEvent_2 = []
        self._PReceivedEvent_4 = []
        self._events.extend([da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_0', PatternExpr_189, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_1', PatternExpr_214, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_2', PatternExpr_247, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_3', PatternExpr_279, sources=None, destinations=None, timestamps=None, record_history=None, handlers=[self._P_handler_278]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PReceivedEvent_4', PatternExpr_330, sources=None, destinations=None, timestamps=None, record_history=True, handlers=[])])

    def setup(self, s, nrequests, **rest_409):
        super().setup(s=s, nrequests=nrequests, **rest_409)
        self._state.s = s
        self._state.nrequests = nrequests
        pass

    def run(self):

        def task():
            self.output('in cs')
            self.output('releasing cs')
        for i in range(self._state.nrequests):
            self.mutex(task)
        self.send(('done', self._id), to=self._state.s)
        super()._label('_st_label_321', block=False)
        p = None

        def UniversalOpExpr_322():
            nonlocal p
            for p in self._state.s:
                if (not PatternExpr_336.match_iter(self._PReceivedEvent_4, _BoundPattern346_=p, SELF_ID=self._id)):
                    return False
            return True
        _st_label_321 = 0
        while (_st_label_321 == 0):
            _st_label_321 += 1
            if UniversalOpExpr_322():
                _st_label_321 += 1
            else:
                super()._label('_st_label_321', block=True)
                _st_label_321 -= 1
        self.output('terminating')

    def mutex(self, task):
        super()._label('request', block=False)
        c = self.logical_clock()
        self.send(('request', c, self._id), to=self._state.s)
        super()._label('_st_label_185', block=False)
        p = c2 = None

        def UniversalOpExpr_187():
            nonlocal p, c2
            for (_, _, (_ConstantPattern206_, c2, p)) in self._PReceivedEvent_0:
                if (_ConstantPattern206_ == 'request'):
                    if (not (PatternExpr_221.match_iter(self._PReceivedEvent_1, _BoundPattern231_=c2, _BoundPattern232_=p, SELF_ID=self._id) or ((c, self._id) < (c2, p)))):
                        return False
            return True
        p = None

        def UniversalOpExpr_240():
            nonlocal p
            for p in self._state.s:
                if (not PatternExpr_254.match_iter(self._PReceivedEvent_2, _BoundPattern264_=c, _BoundPattern265_=p, SELF_ID=self._id)):
                    return False
            return True
        _st_label_185 = 0
        while (_st_label_185 == 0):
            _st_label_185 += 1
            if (UniversalOpExpr_187() and UniversalOpExpr_240()):
                _st_label_185 += 1
            else:
                super()._label('_st_label_185', block=True)
                _st_label_185 -= 1
        super()._label('critical_section', block=False)
        task()
        super()._label('release', block=False)
        self.send(('release', c, self._id), to=self._state.s)

    def _P_handler_278(self, c, p):
        self.send(('ack', c, self._id), to=p)
    _P_handler_278._labels = None
    _P_handler_278._notlabels = None

class Node_(da.NodeProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._events.extend([])

    def run(self):
        nprocs = (int(sys.argv[1]) if (len(sys.argv) > 1) else 10)
        nrequests = (int(sys.argv[2]) if (len(sys.argv) > 2) else 1)
        ps = self.new(P, num=nprocs)
        for p in ps:
            self._setup(p, ((ps - {p}), nrequests))
        self._start(ps)
