# 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: SystemInfo (experimental)
from __future__ import annotations
from .util import event_class, T_JSON_DICT
from dataclasses import dataclass
import enum
import typing

@dataclass
class GPUDevice:
    '''
    Describes a single graphics processor (GPU).
    '''
    #: PCI ID of the GPU vendor, if available; 0 otherwise.
    vendor_id: float

    #: PCI ID of the GPU device, if available; 0 otherwise.
    device_id: float

    #: String description of the GPU vendor, if the PCI ID is not available.
    vendor_string: str

    #: String description of the GPU device, if the PCI ID is not available.
    device_string: str

    #: String description of the GPU driver vendor.
    driver_vendor: str

    #: String description of the GPU driver version.
    driver_version: str

    #: Sub sys ID of the GPU, only available on Windows.
    sub_sys_id: typing.Optional[float] = None

    #: Revision of the GPU, only available on Windows.
    revision: typing.Optional[float] = None

    def to_json(self):
        json = dict()
        json['vendorId'] = self.vendor_id
        json['deviceId'] = self.device_id
        json['vendorString'] = self.vendor_string
        json['deviceString'] = self.device_string
        json['driverVendor'] = self.driver_vendor
        json['driverVersion'] = self.driver_version
        if self.sub_sys_id is not None:
            json['subSysId'] = self.sub_sys_id
        if self.revision is not None:
            json['revision'] = self.revision
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            vendor_id=float(json['vendorId']),
            device_id=float(json['deviceId']),
            vendor_string=str(json['vendorString']),
            device_string=str(json['deviceString']),
            driver_vendor=str(json['driverVendor']),
            driver_version=str(json['driverVersion']),
            sub_sys_id=float(json['subSysId']) if 'subSysId' in json else None,
            revision=float(json['revision']) if 'revision' in json else None,
        )


@dataclass
class Size:
    '''
    Describes the width and height dimensions of an entity.
    '''
    #: Width in pixels.
    width: int

    #: Height in pixels.
    height: int

    def to_json(self):
        json = dict()
        json['width'] = self.width
        json['height'] = self.height
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            width=int(json['width']),
            height=int(json['height']),
        )


@dataclass
class VideoDecodeAcceleratorCapability:
    '''
    Describes a supported video decoding profile with its associated minimum and
    maximum resolutions.
    '''
    #: Video codec profile that is supported, e.g. VP9 Profile 2.
    profile: str

    #: Maximum video dimensions in pixels supported for this ``profile``.
    max_resolution: Size

    #: Minimum video dimensions in pixels supported for this ``profile``.
    min_resolution: Size

    def to_json(self):
        json = dict()
        json['profile'] = self.profile
        json['maxResolution'] = self.max_resolution.to_json()
        json['minResolution'] = self.min_resolution.to_json()
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            profile=str(json['profile']),
            max_resolution=Size.from_json(json['maxResolution']),
            min_resolution=Size.from_json(json['minResolution']),
        )


@dataclass
class VideoEncodeAcceleratorCapability:
    '''
    Describes a supported video encoding profile with its associated maximum
    resolution and maximum framerate.
    '''
    #: Video codec profile that is supported, e.g H264 Main.
    profile: str

    #: Maximum video dimensions in pixels supported for this ``profile``.
    max_resolution: Size

    #: Maximum encoding framerate in frames per second supported for this
    #: ``profile``, as fraction's numerator and denominator, e.g. 24/1 fps,
    #: 24000/1001 fps, etc.
    max_framerate_numerator: int

    max_framerate_denominator: int

    def to_json(self):
        json = dict()
        json['profile'] = self.profile
        json['maxResolution'] = self.max_resolution.to_json()
        json['maxFramerateNumerator'] = self.max_framerate_numerator
        json['maxFramerateDenominator'] = self.max_framerate_denominator
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            profile=str(json['profile']),
            max_resolution=Size.from_json(json['maxResolution']),
            max_framerate_numerator=int(json['maxFramerateNumerator']),
            max_framerate_denominator=int(json['maxFramerateDenominator']),
        )


class SubsamplingFormat(enum.Enum):
    '''
    YUV subsampling type of the pixels of a given image.
    '''
    YUV420 = "yuv420"
    YUV422 = "yuv422"
    YUV444 = "yuv444"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


class ImageType(enum.Enum):
    '''
    Image format of a given image.
    '''
    JPEG = "jpeg"
    WEBP = "webp"
    UNKNOWN = "unknown"

    def to_json(self):
        return self.value

    @classmethod
    def from_json(cls, json):
        return cls(json)


@dataclass
class ImageDecodeAcceleratorCapability:
    '''
    Describes a supported image decoding profile with its associated minimum and
    maximum resolutions and subsampling.
    '''
    #: Image coded, e.g. Jpeg.
    image_type: ImageType

    #: Maximum supported dimensions of the image in pixels.
    max_dimensions: Size

    #: Minimum supported dimensions of the image in pixels.
    min_dimensions: Size

    #: Optional array of supported subsampling formats, e.g. 4:2:0, if known.
    subsamplings: typing.List[SubsamplingFormat]

    def to_json(self):
        json = dict()
        json['imageType'] = self.image_type.to_json()
        json['maxDimensions'] = self.max_dimensions.to_json()
        json['minDimensions'] = self.min_dimensions.to_json()
        json['subsamplings'] = [i.to_json() for i in self.subsamplings]
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            image_type=ImageType.from_json(json['imageType']),
            max_dimensions=Size.from_json(json['maxDimensions']),
            min_dimensions=Size.from_json(json['minDimensions']),
            subsamplings=[SubsamplingFormat.from_json(i) for i in json['subsamplings']],
        )


@dataclass
class GPUInfo:
    '''
    Provides information about the GPU(s) on the system.
    '''
    #: The graphics devices on the system. Element 0 is the primary GPU.
    devices: typing.List[GPUDevice]

    #: An optional array of GPU driver bug workarounds.
    driver_bug_workarounds: typing.List[str]

    #: Supported accelerated video decoding capabilities.
    video_decoding: typing.List[VideoDecodeAcceleratorCapability]

    #: Supported accelerated video encoding capabilities.
    video_encoding: typing.List[VideoEncodeAcceleratorCapability]

    #: Supported accelerated image decoding capabilities.
    image_decoding: typing.List[ImageDecodeAcceleratorCapability]

    #: An optional dictionary of additional GPU related attributes.
    aux_attributes: typing.Optional[dict] = None

    #: An optional dictionary of graphics features and their status.
    feature_status: typing.Optional[dict] = None

    def to_json(self):
        json = dict()
        json['devices'] = [i.to_json() for i in self.devices]
        json['driverBugWorkarounds'] = [i for i in self.driver_bug_workarounds]
        json['videoDecoding'] = [i.to_json() for i in self.video_decoding]
        json['videoEncoding'] = [i.to_json() for i in self.video_encoding]
        json['imageDecoding'] = [i.to_json() for i in self.image_decoding]
        if self.aux_attributes is not None:
            json['auxAttributes'] = self.aux_attributes
        if self.feature_status is not None:
            json['featureStatus'] = self.feature_status
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            devices=[GPUDevice.from_json(i) for i in json['devices']],
            driver_bug_workarounds=[str(i) for i in json['driverBugWorkarounds']],
            video_decoding=[VideoDecodeAcceleratorCapability.from_json(i) for i in json['videoDecoding']],
            video_encoding=[VideoEncodeAcceleratorCapability.from_json(i) for i in json['videoEncoding']],
            image_decoding=[ImageDecodeAcceleratorCapability.from_json(i) for i in json['imageDecoding']],
            aux_attributes=dict(json['auxAttributes']) if 'auxAttributes' in json else None,
            feature_status=dict(json['featureStatus']) if 'featureStatus' in json else None,
        )


@dataclass
class ProcessInfo:
    '''
    Represents process info.
    '''
    #: Specifies process type.
    type_: str

    #: Specifies process id.
    id_: int

    #: Specifies cumulative CPU usage in seconds across all threads of the
    #: process since the process start.
    cpu_time: float

    def to_json(self):
        json = dict()
        json['type'] = self.type_
        json['id'] = self.id_
        json['cpuTime'] = self.cpu_time
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            type_=str(json['type']),
            id_=int(json['id']),
            cpu_time=float(json['cpuTime']),
        )


def get_info() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.Tuple[GPUInfo, str, str, str]]:
    '''
    Returns information about the system.

    :returns: A tuple with the following items:

        0. **gpu** - Information about the GPUs on the system.
        1. **modelName** - A platform-dependent description of the model of the machine. On Mac OS, this is, for example, 'MacBookPro'. Will be the empty string if not supported.
        2. **modelVersion** - A platform-dependent description of the version of the machine. On Mac OS, this is, for example, '10.1'. Will be the empty string if not supported.
        3. **commandLine** - The command line string used to launch the browser. Will be the empty string if not supported.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'SystemInfo.getInfo',
    }
    json = yield cmd_dict
    return (
        GPUInfo.from_json(json['gpu']),
        str(json['modelName']),
        str(json['modelVersion']),
        str(json['commandLine'])
    )


def get_feature_state(
        feature_state: str
    ) -> typing.Generator[T_JSON_DICT,T_JSON_DICT,bool]:
    '''
    Returns information about the feature state.

    :param feature_state:
    :returns: 
    '''
    params: T_JSON_DICT = dict()
    params['featureState'] = feature_state
    cmd_dict: T_JSON_DICT = {
        'method': 'SystemInfo.getFeatureState',
        'params': params,
    }
    json = yield cmd_dict
    return bool(json['featureEnabled'])


def get_process_info() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,typing.List[ProcessInfo]]:
    '''
    Returns information about all running processes.

    :returns: An array of process info blocks.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'SystemInfo.getProcessInfo',
    }
    json = yield cmd_dict
    return [ProcessInfo.from_json(i) for i in json['processInfo']]
