# -*- generated by 1.0.2 -*-
import da
PatternExpr_186 = da.pat.TuplePattern([da.pat.ConstantPattern('vote'), da.pat.FreePattern(None)])
PatternExpr_192 = da.pat.BoundPattern('_BoundPattern193_')
PatternExpr_216 = da.pat.TuplePattern([da.pat.ConstantPattern('vote'), da.pat.ConstantPattern('aborting')])
PatternExpr_223 = da.pat.BoundPattern('_BoundPattern224_')
PatternExpr_244 = da.pat.TuplePattern([da.pat.ConstantPattern('vote'), da.pat.ConstantPattern('ready')])
PatternExpr_251 = da.pat.FreePattern('c')
PatternExpr_283 = da.pat.TuplePattern([da.pat.ConstantPattern('vote'), da.pat.ConstantPattern('ready')])
PatternExpr_290 = da.pat.BoundPattern('_BoundPattern291_')
PatternExpr_315 = da.pat.ConstantPattern('done')
PatternExpr_319 = da.pat.BoundPattern('_BoundPattern320_')
PatternExpr_225 = da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.BoundPattern('_BoundPattern231_')]), da.pat.TuplePattern([da.pat.ConstantPattern('vote'), da.pat.ConstantPattern('aborting')])])
PatternExpr_292 = da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.BoundPattern('_BoundPattern298_')]), da.pat.TuplePattern([da.pat.ConstantPattern('vote'), da.pat.ConstantPattern('ready')])])
PatternExpr_321 = da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.TuplePattern([da.pat.FreePattern(None), da.pat.FreePattern(None), da.pat.BoundPattern('_BoundPattern327_')]), da.pat.ConstantPattern('done')])
PatternExpr_369 = da.pat.ConstantPattern('prepare')
PatternExpr_373 = da.pat.FreePattern('coord')
PatternExpr_397 = da.pat.ConstantPattern('abort')
PatternExpr_406 = da.pat.ConstantPattern('commit')
PatternExpr_410 = da.pat.FreePattern('coord')
_config_object = {}
import sys
from random import randint

class Coordinator(da.DistProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._CoordinatorReceivedEvent_0 = []
        self._CoordinatorReceivedEvent_1 = []
        self._CoordinatorReceivedEvent_2 = []
        self._CoordinatorReceivedEvent_3 = []
        self._CoordinatorReceivedEvent_4 = []
        self._events.extend([da.pat.EventPattern(da.pat.ReceivedEvent, '_CoordinatorReceivedEvent_0', PatternExpr_186, sources=[PatternExpr_192], destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_CoordinatorReceivedEvent_1', PatternExpr_216, sources=[PatternExpr_223], destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_CoordinatorReceivedEvent_2', PatternExpr_244, sources=[PatternExpr_251], destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_CoordinatorReceivedEvent_3', PatternExpr_283, sources=[PatternExpr_290], destinations=None, timestamps=None, record_history=True, handlers=[]), da.pat.EventPattern(da.pat.ReceivedEvent, '_CoordinatorReceivedEvent_4', PatternExpr_315, sources=[PatternExpr_319], destinations=None, timestamps=None, record_history=True, handlers=[])])

    def setup(self, cohorts, **rest_508):
        super().setup(cohorts=cohorts, **rest_508)
        self._state.cohorts = cohorts
        pass

    def run(self):
        self.to_commit()
        self.output('terminating')

    def to_commit(self):
        self.send('prepare', self._state.cohorts)
        super()._label('_st_label_177', block=False)
        c = None

        def UniversalOpExpr_178():
            nonlocal c
            for c in self._state.cohorts:

                def ExistentialOpExpr_184(c):
                    for (_, (_, _, _BoundPattern200_), (_ConstantPattern202_, _)) in self._CoordinatorReceivedEvent_0:
                        if (_BoundPattern200_ == c):
                            if (_ConstantPattern202_ == 'vote'):
                                if True:
                                    return True
                    return False
                if (not ExistentialOpExpr_184(c=c)):
                    return False
            return True
        _st_label_177 = 0
        while (_st_label_177 == 0):
            _st_label_177 += 1
            if UniversalOpExpr_178():
                _st_label_177 += 1
            else:
                super()._label('_st_label_177', block=True)
                _st_label_177 -= 1
        c = None

        def ExistentialOpExpr_209():
            nonlocal c
            for c in self._state.cohorts:
                if PatternExpr_225.match_iter(self._CoordinatorReceivedEvent_1, _BoundPattern231_=c, SELF_ID=self._id):
                    return True
            return False
        if ExistentialOpExpr_209():
            s = {c for c in self._state.cohorts for (_, (_, _, _FreePattern259_), (_ConstantPattern261_, _ConstantPattern263_)) in self._CoordinatorReceivedEvent_2 if (_FreePattern259_ == c) if (_ConstantPattern261_ == 'vote') if (_ConstantPattern263_ == 'ready')}
            self.send('abort', s)
            self.abort()
        c = None

        def UniversalOpExpr_276():
            nonlocal c
            for c in self._state.cohorts:
                if (not PatternExpr_292.match_iter(self._CoordinatorReceivedEvent_3, _BoundPattern298_=c, SELF_ID=self._id)):
                    return False
            return True
        if UniversalOpExpr_276():
            self.send('commit', self._state.cohorts)
            super()._label('_st_label_307', block=False)
            c = None

            def UniversalOpExpr_308():
                nonlocal c
                for c in self._state.cohorts:
                    if (not PatternExpr_321.match_iter(self._CoordinatorReceivedEvent_4, _BoundPattern327_=c, SELF_ID=self._id)):
                        return False
                return True
            _st_label_307 = 0
            while (_st_label_307 == 0):
                _st_label_307 += 1
                if UniversalOpExpr_308():
                    _st_label_307 += 1
                else:
                    super()._label('_st_label_307', block=True)
                    _st_label_307 -= 1
            self.commit()

    def abort(self):
        self.output('abort')

    def commit(self):
        self.output('commit')

class Cohort(da.DistProcess):

    def __init__(self, procimpl, props):
        super().__init__(procimpl, props)
        self._events.extend([da.pat.EventPattern(da.pat.ReceivedEvent, '_CohortReceivedEvent_0', PatternExpr_369, sources=[PatternExpr_373], destinations=None, timestamps=None, record_history=None, handlers=[self._Cohort_handler_368]), da.pat.EventPattern(da.pat.ReceivedEvent, '_CohortReceivedEvent_1', PatternExpr_397, sources=None, destinations=None, timestamps=None, record_history=None, handlers=[self._Cohort_handler_396]), da.pat.EventPattern(da.pat.ReceivedEvent, '_CohortReceivedEvent_2', PatternExpr_406, sources=[PatternExpr_410], destinations=None, timestamps=None, record_history=None, handlers=[self._Cohort_handler_405])])

    def setup(self, failure_rate, **rest_508):
        super().setup(failure_rate=failure_rate, **rest_508)
        self._state.failure_rate = failure_rate
        self._state.terminate = False

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

    def prepared(self):
        return (randint(0, 100) > self._state.failure_rate)

    def ready(self):
        self.output('ready')

    def abort(self):
        self.output('abort')
        self._state.terminate = True

    def commit(self):
        self.output('commit')
        self._state.terminate = True

    def _Cohort_handler_368(self, coord):
        if self.prepared():
            self.send(('vote', 'ready'), coord)
            self.ready()
        else:
            self.send(('vote', 'aborting'), coord)
            self.abort()
    _Cohort_handler_368._labels = None
    _Cohort_handler_368._notlabels = None

    def _Cohort_handler_396(self):
        self.abort()
    _Cohort_handler_396._labels = None
    _Cohort_handler_396._notlabels = None

    def _Cohort_handler_405(self, coord):
        self.send('done', coord)
        self.commit()
    _Cohort_handler_405._labels = None
    _Cohort_handler_405._notlabels = None

class Node_(da.NodeProcess):

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

    def run(self):
        ncohorts = (int(sys.argv[1]) if (len(sys.argv) > 1) else 10)
        fail_rate = (int(sys.argv[2]) if (len(sys.argv) > 2) else 10)
        cohorts = self.new(Cohort, (fail_rate,), num=ncohorts)
        coordinators = self.new(Coordinator, (cohorts,), num=1)
        self._start((cohorts | coordinators))
