from __future__ import annotations
import datetime
from collections.abc import Callable
from dataclasses import dataclass, field
from kiota_abstractions.serialization import AdditionalDataHolder, Parsable, ParseNode, SerializationWriter
from kiota_abstractions.store import BackedModel, BackingStore, BackingStoreFactorySingleton
from typing import Any, Optional, TYPE_CHECKING, Union

if TYPE_CHECKING:
    from .audio_codec import AudioCodec
    from .media_stream_direction import MediaStreamDirection
    from .video_codec import VideoCodec

@dataclass
class MediaStream(AdditionalDataHolder, BackedModel, Parsable):
    # Stores model information.
    backing_store: BackingStore = field(default_factory=BackingStoreFactorySingleton(backing_store_factory=None).backing_store_factory.create_backing_store, repr=False)

    # Stores additional data not described in the OpenAPI description found when deserializing. Can be used for serialization as well.
    additional_data: dict[str, Any] = field(default_factory=dict)
    # Codec name used to encode audio for transmission on the network. Possible values are: unknown, invalid, cn, pcma, pcmu, amrWide, g722, g7221, g7221c, g729, multiChannelAudio, muchv2, opus, satin, satinFullband, rtAudio8, rtAudio16, silk, silkNarrow, silkWide, siren, xmsRta, unknownFutureValue.
    audio_codec: Optional[AudioCodec] = None
    # Average Network Mean Opinion Score degradation for stream. Represents how much the network loss and jitter has impacted the quality of received audio.
    average_audio_degradation: Optional[float] = None
    # Average jitter for the stream computed as specified in RFC 3550, denoted in ISO 8601 format. For example, 1 second is denoted as 'PT1S', where 'P' is the duration designator, 'T' is the time designator, and 'S' is the second designator.
    average_audio_network_jitter: Optional[datetime.timedelta] = None
    # Average estimated bandwidth available between two endpoints in bits per second.
    average_bandwidth_estimate: Optional[int] = None
    # Average duration of the received freezing time in the video stream.
    average_freeze_duration: Optional[datetime.timedelta] = None
    # Average jitter for the stream computed as specified in RFC 3550, denoted in ISO 8601 format. For example, 1 second is denoted as 'PT1S', where 'P' is the duration designator, 'T' is the time designator, and 'S' is the second designator.
    average_jitter: Optional[datetime.timedelta] = None
    # Average packet loss rate for stream.
    average_packet_loss_rate: Optional[float] = None
    # Ratio of the number of audio frames with samples generated by packet loss concealment to the total number of audio frames.
    average_ratio_of_concealed_samples: Optional[float] = None
    # Average frames per second received for all video streams computed over the duration of the session.
    average_received_frame_rate: Optional[float] = None
    # Average network propagation round-trip time computed as specified in RFC 3550, denoted in ISO 8601 format. For example, 1 second is denoted as 'PT1S', where 'P' is the duration designator, 'T' is the time designator, and 'S' is the second designator.
    average_round_trip_time: Optional[datetime.timedelta] = None
    # Average percentage of video frames lost as displayed to the user.
    average_video_frame_loss_percentage: Optional[float] = None
    # Average frames per second received for a video stream, computed over the duration of the session.
    average_video_frame_rate: Optional[float] = None
    # Average fraction of packets lost, as specified in RFC 3550, computed over the duration of the session.
    average_video_packet_loss_rate: Optional[float] = None
    # UTC time when the stream ended. The DateTimeOffset type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z. This field is only available for streams that use the SIP protocol.
    end_date_time: Optional[datetime.datetime] = None
    # Indicates whether the forward error correction (FEC) was used at some point during the session. The default value is null.
    is_audio_forward_error_correction_used: Optional[bool] = None
    # Fraction of the call where frame rate is less than 7.5 frames per second.
    low_frame_rate_ratio: Optional[float] = None
    # Fraction of the call that the client is running less than 70% expected video processing capability.
    low_video_processing_capability_ratio: Optional[float] = None
    # Maximum of audio network jitter computed over each of the 20 second windows during the session, denoted in ISO 8601 format. For example, 1 second is denoted as 'PT1S', where 'P' is the duration designator, 'T' is the time designator, and 'S' is the second designator.
    max_audio_network_jitter: Optional[datetime.timedelta] = None
    # Maximum jitter for the stream computed as specified in RFC 3550, denoted in ISO 8601 format. For example, 1 second is denoted as 'PT1S', where 'P' is the duration designator, 'T' is the time designator, and 'S' is the second designator.
    max_jitter: Optional[datetime.timedelta] = None
    # Maximum packet loss rate for the stream.
    max_packet_loss_rate: Optional[float] = None
    # Maximum ratio of packets concealed by the healer.
    max_ratio_of_concealed_samples: Optional[float] = None
    # Maximum network propagation round-trip time computed as specified in RFC 3550, denoted in ISO 8601 format. For example, 1 second is denoted as 'PT1S', where 'P' is the duration designator, 'T' is the time designator, and 'S' is the second designator.
    max_round_trip_time: Optional[datetime.timedelta] = None
    # The OdataType property
    odata_type: Optional[str] = None
    # Packet count for the stream.
    packet_utilization: Optional[int] = None
    # Packet loss rate after FEC has been applied aggregated across all video streams and codecs.
    post_forward_error_correction_packet_loss_rate: Optional[float] = None
    # Average duration of the received freezing time in the video stream represented in root mean square.
    rms_freeze_duration: Optional[datetime.timedelta] = None
    # UTC time when the stream started. The DateTimeOffset type represents date and time information using ISO 8601 format and is always in UTC time. For example, midnight UTC on Jan 1, 2014 is 2014-01-01T00:00:00Z. This field is only available for streams that use the SIP protocol.
    start_date_time: Optional[datetime.datetime] = None
    # The streamDirection property
    stream_direction: Optional[MediaStreamDirection] = None
    # Unique identifier for the stream.
    stream_id: Optional[str] = None
    # Codec name used to encode video for transmission on the network. Possible values are: unknown, invalid, av1, h263, h264, h264s, h264uc, h265, rtvc1, rtVideo, xrtvc1, unknownFutureValue.
    video_codec: Optional[VideoCodec] = None
    # True if the media stream bypassed the Mediation Server and went straight between client and PSTN Gateway/PBX, false otherwise.
    was_media_bypassed: Optional[bool] = None
    
    @staticmethod
    def create_from_discriminator_value(parse_node: ParseNode) -> MediaStream:
        """
        Creates a new instance of the appropriate class based on discriminator value
        param parse_node: The parse node to use to read the discriminator value and create the object
        Returns: MediaStream
        """
        if parse_node is None:
            raise TypeError("parse_node cannot be null.")
        return MediaStream()
    
    def get_field_deserializers(self,) -> dict[str, Callable[[ParseNode], None]]:
        """
        The deserialization information for the current model
        Returns: dict[str, Callable[[ParseNode], None]]
        """
        from .audio_codec import AudioCodec
        from .media_stream_direction import MediaStreamDirection
        from .video_codec import VideoCodec

        from .audio_codec import AudioCodec
        from .media_stream_direction import MediaStreamDirection
        from .video_codec import VideoCodec

        fields: dict[str, Callable[[Any], None]] = {
            "audioCodec": lambda n : setattr(self, 'audio_codec', n.get_enum_value(AudioCodec)),
            "averageAudioDegradation": lambda n : setattr(self, 'average_audio_degradation', n.get_float_value()),
            "averageAudioNetworkJitter": lambda n : setattr(self, 'average_audio_network_jitter', n.get_timedelta_value()),
            "averageBandwidthEstimate": lambda n : setattr(self, 'average_bandwidth_estimate', n.get_int_value()),
            "averageFreezeDuration": lambda n : setattr(self, 'average_freeze_duration', n.get_timedelta_value()),
            "averageJitter": lambda n : setattr(self, 'average_jitter', n.get_timedelta_value()),
            "averagePacketLossRate": lambda n : setattr(self, 'average_packet_loss_rate', n.get_float_value()),
            "averageRatioOfConcealedSamples": lambda n : setattr(self, 'average_ratio_of_concealed_samples', n.get_float_value()),
            "averageReceivedFrameRate": lambda n : setattr(self, 'average_received_frame_rate', n.get_float_value()),
            "averageRoundTripTime": lambda n : setattr(self, 'average_round_trip_time', n.get_timedelta_value()),
            "averageVideoFrameLossPercentage": lambda n : setattr(self, 'average_video_frame_loss_percentage', n.get_float_value()),
            "averageVideoFrameRate": lambda n : setattr(self, 'average_video_frame_rate', n.get_float_value()),
            "averageVideoPacketLossRate": lambda n : setattr(self, 'average_video_packet_loss_rate', n.get_float_value()),
            "endDateTime": lambda n : setattr(self, 'end_date_time', n.get_datetime_value()),
            "isAudioForwardErrorCorrectionUsed": lambda n : setattr(self, 'is_audio_forward_error_correction_used', n.get_bool_value()),
            "lowFrameRateRatio": lambda n : setattr(self, 'low_frame_rate_ratio', n.get_float_value()),
            "lowVideoProcessingCapabilityRatio": lambda n : setattr(self, 'low_video_processing_capability_ratio', n.get_float_value()),
            "maxAudioNetworkJitter": lambda n : setattr(self, 'max_audio_network_jitter', n.get_timedelta_value()),
            "maxJitter": lambda n : setattr(self, 'max_jitter', n.get_timedelta_value()),
            "maxPacketLossRate": lambda n : setattr(self, 'max_packet_loss_rate', n.get_float_value()),
            "maxRatioOfConcealedSamples": lambda n : setattr(self, 'max_ratio_of_concealed_samples', n.get_float_value()),
            "maxRoundTripTime": lambda n : setattr(self, 'max_round_trip_time', n.get_timedelta_value()),
            "@odata.type": lambda n : setattr(self, 'odata_type', n.get_str_value()),
            "packetUtilization": lambda n : setattr(self, 'packet_utilization', n.get_int_value()),
            "postForwardErrorCorrectionPacketLossRate": lambda n : setattr(self, 'post_forward_error_correction_packet_loss_rate', n.get_float_value()),
            "rmsFreezeDuration": lambda n : setattr(self, 'rms_freeze_duration', n.get_timedelta_value()),
            "startDateTime": lambda n : setattr(self, 'start_date_time', n.get_datetime_value()),
            "streamDirection": lambda n : setattr(self, 'stream_direction', n.get_enum_value(MediaStreamDirection)),
            "streamId": lambda n : setattr(self, 'stream_id', n.get_str_value()),
            "videoCodec": lambda n : setattr(self, 'video_codec', n.get_enum_value(VideoCodec)),
            "wasMediaBypassed": lambda n : setattr(self, 'was_media_bypassed', n.get_bool_value()),
        }
        return fields
    
    def serialize(self,writer: SerializationWriter) -> None:
        """
        Serializes information the current object
        param writer: Serialization writer to use to serialize this model
        Returns: None
        """
        if writer is None:
            raise TypeError("writer cannot be null.")
        writer.write_enum_value("audioCodec", self.audio_codec)
        writer.write_float_value("averageAudioDegradation", self.average_audio_degradation)
        writer.write_timedelta_value("averageAudioNetworkJitter", self.average_audio_network_jitter)
        writer.write_int_value("averageBandwidthEstimate", self.average_bandwidth_estimate)
        writer.write_timedelta_value("averageFreezeDuration", self.average_freeze_duration)
        writer.write_timedelta_value("averageJitter", self.average_jitter)
        writer.write_float_value("averagePacketLossRate", self.average_packet_loss_rate)
        writer.write_float_value("averageRatioOfConcealedSamples", self.average_ratio_of_concealed_samples)
        writer.write_float_value("averageReceivedFrameRate", self.average_received_frame_rate)
        writer.write_timedelta_value("averageRoundTripTime", self.average_round_trip_time)
        writer.write_float_value("averageVideoFrameLossPercentage", self.average_video_frame_loss_percentage)
        writer.write_float_value("averageVideoFrameRate", self.average_video_frame_rate)
        writer.write_float_value("averageVideoPacketLossRate", self.average_video_packet_loss_rate)
        writer.write_datetime_value("endDateTime", self.end_date_time)
        writer.write_bool_value("isAudioForwardErrorCorrectionUsed", self.is_audio_forward_error_correction_used)
        writer.write_float_value("lowFrameRateRatio", self.low_frame_rate_ratio)
        writer.write_float_value("lowVideoProcessingCapabilityRatio", self.low_video_processing_capability_ratio)
        writer.write_timedelta_value("maxAudioNetworkJitter", self.max_audio_network_jitter)
        writer.write_timedelta_value("maxJitter", self.max_jitter)
        writer.write_float_value("maxPacketLossRate", self.max_packet_loss_rate)
        writer.write_float_value("maxRatioOfConcealedSamples", self.max_ratio_of_concealed_samples)
        writer.write_timedelta_value("maxRoundTripTime", self.max_round_trip_time)
        writer.write_str_value("@odata.type", self.odata_type)
        writer.write_int_value("packetUtilization", self.packet_utilization)
        writer.write_float_value("postForwardErrorCorrectionPacketLossRate", self.post_forward_error_correction_packet_loss_rate)
        writer.write_timedelta_value("rmsFreezeDuration", self.rms_freeze_duration)
        writer.write_datetime_value("startDateTime", self.start_date_time)
        writer.write_enum_value("streamDirection", self.stream_direction)
        writer.write_str_value("streamId", self.stream_id)
        writer.write_enum_value("videoCodec", self.video_codec)
        writer.write_bool_value("wasMediaBypassed", self.was_media_bypassed)
        writer.write_additional_data_value(self.additional_data)
    

