# DO NOT EDIT THIS FILE!
#
# This file is generated from the CDP specification. If you need to make
# changes, edit the generator and regenerate all of the modules.
#
# CDP domain: WebAudio (experimental)

from __future__ import annotations
from cdp.util import event_class, T_JSON_DICT
from dataclasses import dataclass
import enum
import typing


class ContextId(str):
    '''
    Context's UUID in string
    '''
    def to_json(self) -> str:
        return self

    @classmethod
    def from_json(cls, json: str) -> ContextId:
        return cls(json)

    def __repr__(self):
        return 'ContextId({})'.format(super().__repr__())


class ContextType(enum.Enum):
    '''
    Enum of BaseAudioContext types
    '''
    REALTIME = "realtime"
    OFFLINE = "offline"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> ContextType:
        return cls(json)


class ContextState(enum.Enum):
    '''
    Enum of AudioContextState from the spec
    '''
    SUSPENDED = "suspended"
    RUNNING = "running"
    CLOSED = "closed"

    def to_json(self) -> str:
        return self.value

    @classmethod
    def from_json(cls, json: str) -> ContextState:
        return cls(json)


@dataclass
class ContextRealtimeData:
    '''
    Fields in AudioContext that change in real-time.
    '''
    #: The current context time in second in BaseAudioContext.
    current_time: float

    #: The time spent on rendering graph divided by render qunatum duration,
    #: and multiplied by 100. 100 means the audio renderer reached the full
    #: capacity and glitch may occur.
    render_capacity: float

    #: A running mean of callback interval.
    callback_interval_mean: float

    #: A running variance of callback interval.
    callback_interval_variance: float

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json['currentTime'] = self.current_time
        json['renderCapacity'] = self.render_capacity
        json['callbackIntervalMean'] = self.callback_interval_mean
        json['callbackIntervalVariance'] = self.callback_interval_variance
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ContextRealtimeData:
        return cls(
            current_time=float(json['currentTime']),
            render_capacity=float(json['renderCapacity']),
            callback_interval_mean=float(json['callbackIntervalMean']),
            callback_interval_variance=float(json['callbackIntervalVariance']),
        )


@dataclass
class BaseAudioContext:
    '''
    Protocol object for BaseAudioContext
    '''
    context_id: ContextId

    context_type: ContextType

    context_state: ContextState

    #: Platform-dependent callback buffer size.
    callback_buffer_size: float

    #: Number of output channels supported by audio hardware in use.
    max_output_channel_count: float

    #: Context sample rate.
    sample_rate: float

    realtime_data: typing.Optional[ContextRealtimeData] = None

    def to_json(self) -> T_JSON_DICT:
        json: T_JSON_DICT = dict()
        json['contextId'] = self.context_id.to_json()
        json['contextType'] = self.context_type.to_json()
        json['contextState'] = self.context_state.to_json()
        json['callbackBufferSize'] = self.callback_buffer_size
        json['maxOutputChannelCount'] = self.max_output_channel_count
        json['sampleRate'] = self.sample_rate
        if self.realtime_data is not None:
            json['realtimeData'] = self.realtime_data.to_json()
        return json

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> BaseAudioContext:
        return cls(
            context_id=ContextId.from_json(json['contextId']),
            context_type=ContextType.from_json(json['contextType']),
            context_state=ContextState.from_json(json['contextState']),
            callback_buffer_size=float(json['callbackBufferSize']),
            max_output_channel_count=float(json['maxOutputChannelCount']),
            sample_rate=float(json['sampleRate']),
            realtime_data=ContextRealtimeData.from_json(json['realtimeData']) if 'realtimeData' in json else None,
        )


def enable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Enables the WebAudio domain and starts sending context lifetime events.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'WebAudio.enable',
    }
    json = yield cmd_dict


def disable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Disables the WebAudio domain.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'WebAudio.disable',
    }
    json = yield cmd_dict


def get_realtime_data(
        context_id: ContextId
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,ContextRealtimeData]:
    '''
    Fetch the realtime data from the registered contexts.

    :param context_id:
    :returns: 
    '''
    params: T_JSON_DICT = dict()
    params['contextId'] = context_id.to_json()
    cmd_dict: T_JSON_DICT = {
        'method': 'WebAudio.getRealtimeData',
        'params': params,
    }
    json = yield cmd_dict
    return ContextRealtimeData.from_json(json['realtimeData'])


@event_class('WebAudio.contextCreated')
@dataclass
class ContextCreated:
    '''
    Notifies that a new BaseAudioContext has been created.
    '''
    context: BaseAudioContext

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ContextCreated:
        return cls(
            context=BaseAudioContext.from_json(json['context'])
        )


@event_class('WebAudio.contextDestroyed')
@dataclass
class ContextDestroyed:
    '''
    Notifies that existing BaseAudioContext has been destroyed.
    '''
    context_id: ContextId

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ContextDestroyed:
        return cls(
            context_id=ContextId.from_json(json['contextId'])
        )


@event_class('WebAudio.contextChanged')
@dataclass
class ContextChanged:
    '''
    Notifies that existing BaseAudioContext has changed some properties (id stays the same)..
    '''
    context: BaseAudioContext

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ContextChanged:
        return cls(
            context=BaseAudioContext.from_json(json['context'])
        )
