# -*- generated by 1.0.12 -*-
import da
PatternExpr_176 = da.pat.TuplePattern([da.pat.ConstantPattern('Ping')])
PatternExpr_181 = da.pat.FreePattern('p')
PatternExpr_227 = da.pat.TuplePattern([da.pat.ConstantPattern('Pong')])
PatternExpr_232 = da.pat.FreePattern('rclk')
PatternExpr_252 = da.pat.TuplePattern([da.pat.ConstantPattern('Pong')])
_config_object = {}
import sys

class Pong(da.DistProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._events.extend([da.pat.EventPattern(da.pat.ReceivedEvent, '_PongReceivedEvent_0', PatternExpr_176, sources=[PatternExpr_181], destinations=None, timestamps=None, record_history=None, handlers=[self._Pong_handler_175])])

    def setup(self, total_pings, **rest_324):
        super().setup(total_pings=total_pings, **rest_324)
        self._state.total_pings = total_pings
        pass

    def run(self):
        super()._label('_st_label_169', block=False)
        _st_label_169 = 0
        while (_st_label_169 == 0):
            _st_label_169 += 1
            if (self._state.total_pings == 0):
                _st_label_169 += 1
            else:
                super()._label('_st_label_169', block=True)
                _st_label_169 -= 1

    def _Pong_handler_175(self, p):
        self.output('Pinged')
        self.send(('Pong',), to=p)
        self._state.total_pings -= 1
    _Pong_handler_175._labels = None
    _Pong_handler_175._notlabels = None

class Ping(da.DistProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._PingReceivedEvent_0 = []
        self._events.extend([da.pat.EventPattern(da.pat.ReceivedEvent, '_PingReceivedEvent_0', PatternExpr_227, sources=None, destinations=None, timestamps=[PatternExpr_232], record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PingReceivedEvent_1', PatternExpr_252, sources=None, destinations=None, timestamps=None, record_history=None, handlers=[self._Ping_handler_251])])

    def setup(self, p, nrounds, **rest_324):
        super().setup(p=p, nrounds=nrounds, **rest_324)
        self._state.p = p
        self._state.nrounds = nrounds
        pass

    def run(self):
        for i in range(self._state.nrounds):
            clk = self.logical_clock()
            self.send(('Ping',), to=self._state.p)
            super()._label('_st_label_224', block=False)
            rclk = None

            def ExistentialOpExpr_225():
                nonlocal rclk
                for (_, (rclk, _, _), (_ConstantPattern243_,)) in self._PingReceivedEvent_0:
                    if (_ConstantPattern243_ == 'Pong'):
                        if (rclk > clk):
                            return True
                return False
            _st_label_224 = 0
            while (_st_label_224 == 0):
                _st_label_224 += 1
                if ExistentialOpExpr_225():
                    _st_label_224 += 1
                else:
                    super()._label('_st_label_224', block=True)
                    _st_label_224 -= 1
            else:
                if (_st_label_224 != 2):
                    continue
            if (_st_label_224 != 2):
                break

    def _Ping_handler_251(self):
        self.output('Ponged.')
    _Ping_handler_251._labels = None
    _Ping_handler_251._notlabels = None

class Node_(da.NodeProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._events.extend([])
    _config_object = {'clock': 'Lamport'}

    def run(self):
        nrounds = (int(sys.argv[1]) if (len(sys.argv) > 1) else 3)
        npings = (int(sys.argv[2]) if (len(sys.argv) > 2) else 3)
        pong = self.new(Pong, [(nrounds * npings)], num=1)
        ping = self.new(Ping, num=npings)
        self._setup(ping, (pong, nrounds))
        self._start(pong)
        self._start(ping)
