# This file was generated by the "yardl" tool. DO NOT EDIT.

# pyright: reportUnusedImport=false

import abc
import collections.abc
import datetime
import typing

import numpy as np
import numpy.typing as npt

from .types import *
from .yardl_types import ProtocolError
from . import yardl_types as yardl

class PETSIRDWriterBase(abc.ABC):
    """Abstract writer for the PETSIRD protocol.

    Definition of the stream of data
    """


    def __init__(self) -> None:
        self._state = 0

    schema = r"""{"protocol":{"name":"PETSIRD","sequence":[{"name":"header","type":"PETSIRD.Header"},{"name":"timeBlocks","type":{"stream":{"items":"PETSIRD.TimeBlock"}}}]},"types":[{"name":"AliveTimeFractions","fields":[{"name":"singlesAliveTimeFractions","type":{"vector":{"items":"PETSIRD.SinglesAliveTimeFractions"}}},{"name":"moduleCoincidenceAliveTimeFractions","type":[null,{"vector":{"items":{"vector":{"items":"PETSIRD.ModuleCoincidenceAliveTimeFractions"}}}}]}]},{"name":"AnnulusShape","fields":[{"name":"innerRadius","type":"float32"},{"name":"outerRadius","type":"float32"},{"name":"thickness","type":"float32"},{"name":"angularRange","type":{"vector":{"items":"float32","length":2}}}]},{"name":"Atom","fields":[{"name":"massNumber","type":"uint32"},{"name":"atomicNumber","type":"uint32"}]},{"name":"BedMovementTimeBlock","fields":[{"name":"timeInterval","type":"PETSIRD.TimeInterval"},{"name":"transform","type":"PETSIRD.RigidTransformation"}]},{"name":"BinEdges","fields":[{"name":"edges","type":{"array":{"items":"float32","dimensions":1}}}]},{"name":"BoxShape","fields":[{"name":"corners","type":{"vector":{"items":"PETSIRD.Coordinate","length":8}}}]},{"name":"BoxSolidVolume","type":{"name":"PETSIRD.SolidVolume","typeArguments":["PETSIRD.BoxShape"]}},{"name":"BulkMaterial","fields":[{"name":"id","type":"uint32"},{"name":"name","type":"string"},{"name":"density","type":"float32"},{"name":"atoms","type":{"vector":{"items":"PETSIRD.Atom"}}},{"name":"massFractions","type":{"vector":{"items":"float32"}}}]},{"name":"CoincidenceEvent","fields":[{"name":"detectionBins","type":{"vector":{"items":"PETSIRD.DetectionBin","length":2}}},{"name":"tofIdx","type":"uint32"}]},{"name":"CoincidencePolicy","values":[{"symbol":"rejectHigherMultiples","value":0},{"symbol":"multiplesAsAllCoincidences","value":1},{"symbol":"multiplesAsSequentialCoincidences","value":2},{"symbol":"other","value":3}]},{"name":"Coordinate","fields":[{"name":"c","type":{"array":{"items":"float32","dimensions":[{"length":3}]}}}]},{"name":"DeadTimeTimeBlock","fields":[{"name":"timeInterval","type":"PETSIRD.TimeInterval"},{"name":"aliveTimeFractions","type":"PETSIRD.AliveTimeFractions"}]},{"name":"DetectionBin","type":"uint32"},{"name":"DetectionBinEfficiencies","type":{"array":{"items":"float32","dimensions":[{"name":"detectionBin"}]}}},{"name":"DetectionEfficiencies","fields":[{"name":"methodDescription","type":"string"},{"name":"calibrationFactor","type":"float32"},{"name":"detectionBinEfficiencies","type":[null,{"vector":{"items":"PETSIRD.DetectionBinEfficiencies"}}]},{"name":"modulePairSGIDLUT","type":[null,{"vector":{"items":{"vector":{"items":"PETSIRD.ModulePairSGIDLUT"}}}}]},{"name":"modulePairEfficienciesVectors","type":[null,{"vector":{"items":{"vector":{"items":"PETSIRD.ModulePairEfficienciesVector"}}}}]}]},{"name":"DetectorModule","fields":[{"name":"detectingElements","type":"PETSIRD.ReplicatedBoxSolidVolume"},{"name":"nonDetectingElements","type":{"vector":{"items":"PETSIRD.ReplicatedGenericSolidVolume"}}}]},{"name":"EventTimeBlock","fields":[{"name":"timeInterval","type":"PETSIRD.TimeInterval"},{"name":"singleEvents","type":{"vector":{"items":"PETSIRD.ListOfSingleEvents"}}},{"name":"promptEvents","type":{"vector":{"items":{"vector":{"items":"PETSIRD.ListOfCoincidenceEvents"}}}}},{"name":"delayedEvents","type":{"vector":{"items":{"vector":{"items":"PETSIRD.ListOfCoincidenceEvents"}}}}},{"name":"tripleEvents","type":{"vector":{"items":{"vector":{"items":{"vector":{"items":"PETSIRD.ListOfTripleEvents"}}}}}}},{"name":"quadrupleEvents","type":{"vector":{"items":{"vector":{"items":{"vector":{"items":{"vector":{"items":"PETSIRD.ListOfQuadrupleEvents"}}}}}}}}}]},{"name":"ExamInformation","fields":[{"name":"subject","type":"PETSIRD.Subject"},{"name":"institution","type":"PETSIRD.Institution"},{"name":"protocol","type":[null,"string"]},{"name":"startOfAcquisition","type":[null,"datetime"]},{"name":"externalSignals","type":{"vector":{"items":"PETSIRD.ExternalSignal"}}}]},{"name":"ExternalSignal","fields":[{"name":"type","type":"PETSIRD.ExternalSignalTypeEnum"},{"name":"description","type":"string"},{"name":"id","type":"uint32"}]},{"name":"ExternalSignalTimeBlock","fields":[{"name":"timeInterval","type":"PETSIRD.TimeInterval"},{"name":"signalID","type":"uint32"},{"name":"signalValues","type":{"vector":{"items":"float32"}}}]},{"name":"ExternalSignalTypeEnum","values":[{"symbol":"ecgTrace","value":0},{"symbol":"ecgTrigger","value":1},{"symbol":"respTrace","value":2},{"symbol":"respTrigger","value":3},{"symbol":"otherMotionSignal","value":4},{"symbol":"otherMotionTrigger","value":5},{"symbol":"externalSync","value":6},{"symbol":"mrPulseStart","value":7},{"symbol":"other","value":8}]},{"name":"GantryMovementTimeBlock","fields":[{"name":"timeInterval","type":"PETSIRD.TimeInterval"},{"name":"transform","type":"PETSIRD.RigidTransformation"}]},{"name":"GenericSolidVolume","type":{"name":"PETSIRD.SolidVolume","typeArguments":["PETSIRD.GeometricShape"]}},{"name":"GeometricShape","type":[{"tag":"BoxShape","type":"PETSIRD.BoxShape"},{"tag":"AnnulusShape","type":"PETSIRD.AnnulusShape"}]},{"name":"Header","fields":[{"name":"scanner","type":"PETSIRD.ScannerInformation"},{"name":"exam","type":[null,"PETSIRD.ExamInformation"]}]},{"name":"Institution","fields":[{"name":"name","type":"string"},{"name":"address","type":"string"}]},{"name":"ListOfCoincidenceEvents","type":{"vector":{"items":"PETSIRD.CoincidenceEvent"}}},{"name":"ListOfQuadrupleEvents","type":{"vector":{"items":"PETSIRD.TripleEvent"}}},{"name":"ListOfSingleEvents","type":{"vector":{"items":"PETSIRD.SingleEvent"}}},{"name":"ListOfTripleEvents","type":{"vector":{"items":"PETSIRD.TripleEvent"}}},{"name":"ModuleCoincidenceAliveTimeFractions","type":{"array":{"items":"float32","dimensions":[{"name":"moduleId0"},{"name":"moduleId1"}]}}},{"name":"ModulePairEfficiencies","fields":[{"name":"values","type":{"array":{"items":"float32","dimensions":[{"name":"detectionBin1"},{"name":"detectionBin2"}]}}},{"name":"sgid","type":"PETSIRD.SGID"}]},{"name":"ModulePairEfficienciesVector","type":{"vector":{"items":"PETSIRD.ModulePairEfficiencies"}}},{"name":"ModulePairSGIDLUT","type":{"array":{"items":"int32","dimensions":[{"name":"moduleIndex1"},{"name":"moduleIndex2"}]}}},{"name":"QuadrupleEventPolicy","values":[{"symbol":"rejectHigherMultiples","value":0},{"symbol":"other","value":1}]},{"name":"ReplicatedBoxSolidVolume","type":{"name":"PETSIRD.ReplicatedObject","typeArguments":["PETSIRD.BoxSolidVolume"]}},{"name":"ReplicatedDetectorModule","type":{"name":"PETSIRD.ReplicatedObject","typeArguments":["PETSIRD.DetectorModule"]}},{"name":"ReplicatedGenericSolidVolume","type":{"name":"PETSIRD.ReplicatedObject","typeArguments":["PETSIRD.GenericSolidVolume"]}},{"name":"ReplicatedObject","typeParameters":["T"],"fields":[{"name":"object","type":"T"},{"name":"transforms","type":{"vector":{"items":"PETSIRD.RigidTransformation"}}}]},{"name":"RigidTransformation","fields":[{"name":"matrix","type":{"array":{"items":"float32","dimensions":[{"length":3},{"length":4}]}}}]},{"name":"SGID","type":"uint32"},{"name":"ScannerGeometry","fields":[{"name":"replicatedModules","type":{"vector":{"items":"PETSIRD.ReplicatedDetectorModule"}}},{"name":"nonDetectingVolumes","type":[null,{"vector":{"items":"PETSIRD.GenericSolidVolume"}}]}]},{"name":"ScannerInformation","fields":[{"name":"modelName","type":"string"},{"name":"scannerGeometry","type":"PETSIRD.ScannerGeometry"},{"name":"bulkMaterials","type":{"vector":{"items":"PETSIRD.BulkMaterial"}}},{"name":"gantryAlignment","type":[null,"PETSIRD.RigidTransformation"]},{"name":"tofBinEdges","type":{"vector":{"items":{"vector":{"items":"PETSIRD.BinEdges"}}}}},{"name":"tofResolution","type":{"vector":{"items":{"vector":{"items":"float32"}}}}},{"name":"eventEnergyBinEdges","type":{"vector":{"items":"PETSIRD.BinEdges"}}},{"name":"energyResolutionAt511","type":{"vector":{"items":"float32"}}},{"name":"singlesHistogramLevel","type":"PETSIRD.SinglesHistogramLevelType"},{"name":"singlesHistogramEnergyBinEdges","type":{"vector":{"items":"PETSIRD.BinEdges"}}},{"name":"singleEventPolicy","type":"PETSIRD.SingleEventPolicy"},{"name":"promptEventPolicy","type":"PETSIRD.CoincidencePolicy"},{"name":"delayedEventPolicy","type":"PETSIRD.CoincidencePolicy"},{"name":"tripleEventPolicy","type":"PETSIRD.TripleEventPolicy"},{"name":"quadrupleEventPolicy","type":"PETSIRD.QuadrupleEventPolicy"},{"name":"singleEventsAreStored","type":"bool"},{"name":"promptEventsAreStored","type":"bool"},{"name":"delayedEventsAreStored","type":"bool"},{"name":"tripleEventsAreStored","type":"bool"},{"name":"quadrupleEventsAreStored","type":"bool"},{"name":"detectionEfficiencies","type":"PETSIRD.DetectionEfficiencies"}]},{"name":"SingleEvent","fields":[{"name":"detectionBin","type":"PETSIRD.DetectionBin"},{"name":"timeOffsetInTimeBlock","type":"uint32"}]},{"name":"SingleEventPolicy","values":[{"symbol":"all","value":0},{"symbol":"rejectIfNotInCoincidence","value":1},{"symbol":"other","value":2}]},{"name":"SinglesAliveTimeFractions","type":{"array":{"items":"float32","dimensions":[{"name":"detectionBin"}]}}},{"name":"SinglesHistogram","type":{"array":{"items":"uint64","dimensions":[{"name":"singlesDetectionBin"}]}}},{"name":"SinglesHistogramLevelType","values":[{"symbol":"none","value":0},{"symbol":"module","value":1},{"symbol":"all","value":2}]},{"name":"SinglesHistogramTimeBlock","fields":[{"name":"timeInterval","type":"PETSIRD.TimeInterval"},{"name":"singlesHistograms","type":{"vector":{"items":"PETSIRD.SinglesHistogram"}}}]},{"name":"SolidVolume","typeParameters":["Shape"],"fields":[{"name":"shape","type":"Shape"},{"name":"materialId","type":"uint32"}]},{"name":"Subject","fields":[{"name":"name","type":[null,"string"]},{"name":"id","type":"string"}]},{"name":"TimeBlock","type":[{"tag":"EventTimeBlock","type":"PETSIRD.EventTimeBlock"},{"tag":"ExternalSignalTimeBlock","type":"PETSIRD.ExternalSignalTimeBlock"},{"tag":"BedMovementTimeBlock","type":"PETSIRD.BedMovementTimeBlock"},{"tag":"GantryMovementTimeBlock","type":"PETSIRD.GantryMovementTimeBlock"},{"tag":"DeadTimeTimeBlock","type":"PETSIRD.DeadTimeTimeBlock"},{"tag":"SinglesHistogramTimeBlock","type":"PETSIRD.SinglesHistogramTimeBlock"}]},{"name":"TimeInterval","fields":[{"name":"start","type":"uint32"},{"name":"stop","type":"uint32"}]},{"name":"TripleEvent","fields":[{"name":"detectionBins","type":{"vector":{"items":"PETSIRD.DetectionBin","length":3}}},{"name":"tofIndices","type":{"vector":{"items":"uint32","length":2}}}]},{"name":"TripleEventPolicy","values":[{"symbol":"rejectHigherMultiples","value":0},{"symbol":"other","value":1}]}]}"""

    def close(self) -> None:
        if self._state == 3:
            try:
                self._end_stream()
                return
            finally:
                self._close()
        self._close()
        if self._state != 4:
            expected_method = self._state_to_method_name((self._state + 1) & ~1)
            raise ProtocolError(f"Protocol writer closed before all steps were called. Expected to call to '{expected_method}'.")

    def __enter__(self):
        return self

    def __exit__(self, exc_type: typing.Optional[type[BaseException]], exc: typing.Optional[BaseException], traceback: object) -> None:
        try:
            self.close()
        except Exception as e:
            if exc is None:
                raise e

    def write_header(self, value: Header) -> None:
        """Ordinal 0"""

        if self._state != 0:
            self._raise_unexpected_state(0)

        self._write_header(value)
        self._state = 2

    def write_time_blocks(self, value: collections.abc.Iterable[TimeBlock]) -> None:
        """Ordinal 1"""

        if self._state & ~1 != 2:
            self._raise_unexpected_state(2)

        self._write_time_blocks(value)
        self._state = 3

    @abc.abstractmethod
    def _write_header(self, value: Header) -> None:
        raise NotImplementedError()

    @abc.abstractmethod
    def _write_time_blocks(self, value: collections.abc.Iterable[TimeBlock]) -> None:
        raise NotImplementedError()

    @abc.abstractmethod
    def _close(self) -> None:
        pass

    @abc.abstractmethod
    def _end_stream(self) -> None:
        pass

    def _raise_unexpected_state(self, actual: int) -> None:
        expected_method = self._state_to_method_name(self._state)
        actual_method = self._state_to_method_name(actual)
        raise ProtocolError(f"Expected to call to '{expected_method}' but received call to '{actual_method}'.")

    def _state_to_method_name(self, state: int) -> str:
        if state == 0:
            return 'write_header'
        if state == 2:
            return 'write_time_blocks'
        return "<unknown>"

class PETSIRDReaderBase(abc.ABC):
    """Abstract reader for the PETSIRD protocol.

    Definition of the stream of data
    """


    def __init__(self) -> None:
        self._state = 0

    def close(self) -> None:
        self._close()
        if self._state != 4:
            if self._state % 2 == 1:
                previous_method = self._state_to_method_name(self._state - 1)
                raise ProtocolError(f"Protocol reader closed before all data was consumed. The iterable returned by '{previous_method}' was not fully consumed.")
            else:
                expected_method = self._state_to_method_name(self._state)
                raise ProtocolError(f"Protocol reader closed before all data was consumed. Expected call to '{expected_method}'.")
            	

    schema = PETSIRDWriterBase.schema

    def __enter__(self):
        return self

    def __exit__(self, exc_type: typing.Optional[type[BaseException]], exc: typing.Optional[BaseException], traceback: object) -> None:
        try:
            self.close()
        except Exception as e:
            if exc is None:
                raise e

    @abc.abstractmethod
    def _close(self) -> None:
        raise NotImplementedError()

    def read_header(self) -> Header:
        """Ordinal 0"""

        if self._state != 0:
            self._raise_unexpected_state(0)

        value = self._read_header()
        self._state = 2
        return value

    def read_time_blocks(self) -> collections.abc.Iterable[TimeBlock]:
        """Ordinal 1"""

        if self._state != 2:
            self._raise_unexpected_state(2)

        value = self._read_time_blocks()
        self._state = 3
        return self._wrap_iterable(value, 4)

    def copy_to(self, writer: PETSIRDWriterBase) -> None:
        writer.write_header(self.read_header())
        writer.write_time_blocks(self.read_time_blocks())

    @abc.abstractmethod
    def _read_header(self) -> Header:
        raise NotImplementedError()

    @abc.abstractmethod
    def _read_time_blocks(self) -> collections.abc.Iterable[TimeBlock]:
        raise NotImplementedError()

    T = typing.TypeVar('T')
    def _wrap_iterable(self, iterable: collections.abc.Iterable[T], final_state: int) -> collections.abc.Iterable[T]:
        yield from iterable
        self._state = final_state

    def _raise_unexpected_state(self, actual: int) -> None:
        actual_method = self._state_to_method_name(actual)
        if self._state % 2 == 1:
            previous_method = self._state_to_method_name(self._state - 1)
            raise ProtocolError(f"Received call to '{actual_method}' but the iterable returned by '{previous_method}' was not fully consumed.")
        else:
            expected_method = self._state_to_method_name(self._state)
            raise ProtocolError(f"Expected to call to '{expected_method}' but received call to '{actual_method}'.")
        	
    def _state_to_method_name(self, state: int) -> str:
        if state == 0:
            return 'read_header'
        if state == 2:
            return 'read_time_blocks'
        return "<unknown>"

