# -*- generated by 1.0.6 -*-
import da
PatternExpr_177 = da.pat.TuplePattern([da.pat.ConstantPattern('Ping')])
PatternExpr_182 = da.pat.FreePattern('p')
PatternExpr_201 = da.pat.TuplePattern([da.pat.ConstantPattern('Ping')])
PatternExpr_206 = da.pat.FreePattern('p')
PatternExpr_249 = da.pat.TuplePattern([da.pat.ConstantPattern('Pong')])
PatternExpr_254 = da.pat.FreePattern('rclk')
PatternExpr_274 = 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._PongReceivedEvent_0 = []
        self._events.extend([da.pat.EventPattern(da.pat.ReceivedEvent, '_PongReceivedEvent_0', PatternExpr_177, sources=[PatternExpr_182], destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PongReceivedEvent_1', PatternExpr_201, sources=[PatternExpr_206], destinations=None, timestamps=None, record_history=None, handlers=[self._Pong_handler_200])])

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

    def run(self):
        a = False
        super()._label('_st_label_172', block=False)
        _st_label_172 = 0
        while (_st_label_172 == 0):
            _st_label_172 += 1
            if (len([p for (_, (_, _, p), (_ConstantPattern193_,)) in self._PongReceivedEvent_0 if (_ConstantPattern193_ == 'Ping')]) == self._state.total_pings):
                _st_label_172 += 1
            else:
                super()._label('_st_label_172', block=True)
                _st_label_172 -= 1

    def _Pong_handler_200(self, p):
        self.output('Pinged')
        self.send(('Pong',), to=p)
    _Pong_handler_200._labels = None
    _Pong_handler_200._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_249, sources=None, destinations=None, timestamps=[PatternExpr_254], record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_PingReceivedEvent_1', PatternExpr_274, sources=None, destinations=None, timestamps=None, record_history=None, handlers=[self._Ping_handler_273])])

    def setup(self, p, nrounds, **rest_346):
        super().setup(p=p, nrounds=nrounds, **rest_346)
        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_246', block=False)
            rclk = None

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

    def _Ping_handler_273(self):
        self.output('Ponged.')
    _Ping_handler_273._labels = None
    _Ping_handler_273._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)
