
# Generated by OTF2 Template Engine

import _otf2
from . import events
from .attribute_list import AttributeList
from .definitions import Location


class BufferedEventReader(object):
    def __init__(self, reader, batch_events):
        self.reader = reader
        self.batch_events = batch_events
        self._selected_locations = None
        self._handle = None

    def _append(self, event_type, location_ref, time, _, attribute_list, *args):
        event = event_type._construct(self.reader.definitions, time, *args)
        event.attributes = AttributeList._construct(self.reader.definitions, attribute_list)
        location = self.reader.definitions.locations[location_ref]
        t = (location, event)
        self.buffer.append(t)

    def __call__(self, locations):
        if self._selected_locations is not None:
            raise RuntimeError("Cannot specify locations for an event reader twice.")
        if isinstance(locations, Location):
            locations = locations,

        self._selected_locations = locations

        return self

    def __iter__(self):
        if self._handle is not None:
            raise EOFError("Cannot iterate over trace twice.")
        self._handle = self.reader._get_global_evt_reader_handle(self._selected_locations)

        reader_callbacks = _otf2.GlobalEvtReaderCallbacks_New()
        self._set_global_event_reader_callbacks(reader_callbacks)
        _otf2.GlobalEvtReader_SetCallbacks(self._handle, reader_callbacks, None)
        _otf2.GlobalEvtReaderCallbacks_Delete(reader_callbacks)

        while True:
            self.buffer = []
            read_events = _otf2.GlobalEvtReader_ReadEvents(self._handle, self.batch_events)
            for loc_event in self.buffer:
                yield loc_event

            if read_events < self.batch_events:
                break

    def __len__(self):
        locations = self._selected_locations
        if locations is None:
            locations = self.reader._locations
        return sum(location.number_of_events for location in locations)

    def _set_global_event_reader_callbacks(self, cbs):
@otf2 for event in events:
        _otf2.GlobalEvtReaderCallbacks_Set@@event.name@@Callback(cbs, self._@@event.lower@@)
@otf2 endfor
@otf2 for event in events:

    def _@@event.lower@@(self, *args):
        self._append(events.@@event.name@@, *args)
@otf2 endfor
