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


@dataclass
class Annotation:
    '''
    Tool annotations
    '''
    #: A hint indicating that the tool does not modify any state.
    read_only: typing.Optional[bool] = None

    #: If the declarative tool was declared with the autosubmit attribute.
    autosubmit: typing.Optional[bool] = None

    def to_json(self):
        json = dict()
        if self.read_only is not None:
            json['readOnly'] = self.read_only
        if self.autosubmit is not None:
            json['autosubmit'] = self.autosubmit
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            read_only=bool(json['readOnly']) if 'readOnly' in json else None,
            autosubmit=bool(json['autosubmit']) if 'autosubmit' in json else None,
        )


class InvocationStatus(enum.Enum):
    '''
    Represents the status of a tool invocation.
    '''
    SUCCESS = "Success"
    CANCELED = "Canceled"
    ERROR = "Error"

    def to_json(self):
        return self.value

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


@dataclass
class Tool:
    '''
    Definition of a tool that can be invoked.
    '''
    #: Tool name.
    name: str

    #: Tool description.
    description: str

    #: Frame identifier associated with the tool registration.
    frame_id: page.FrameId

    #: Schema for the tool's input parameters.
    input_schema: typing.Optional[dict] = None

    #: Optional annotations for the tool.
    annotations: typing.Optional[Annotation] = None

    #: Optional node ID for declarative tools.
    backend_node_id: typing.Optional[dom.BackendNodeId] = None

    #: The stack trace at the time of the registration.
    stack_trace: typing.Optional[runtime.StackTrace] = None

    def to_json(self):
        json = dict()
        json['name'] = self.name
        json['description'] = self.description
        json['frameId'] = self.frame_id.to_json()
        if self.input_schema is not None:
            json['inputSchema'] = self.input_schema
        if self.annotations is not None:
            json['annotations'] = self.annotations.to_json()
        if self.backend_node_id is not None:
            json['backendNodeId'] = self.backend_node_id.to_json()
        if self.stack_trace is not None:
            json['stackTrace'] = self.stack_trace.to_json()
        return json

    @classmethod
    def from_json(cls, json):
        return cls(
            name=str(json['name']),
            description=str(json['description']),
            frame_id=page.FrameId.from_json(json['frameId']),
            input_schema=dict(json['inputSchema']) if 'inputSchema' in json else None,
            annotations=Annotation.from_json(json['annotations']) if 'annotations' in json else None,
            backend_node_id=dom.BackendNodeId.from_json(json['backendNodeId']) if 'backendNodeId' in json else None,
            stack_trace=runtime.StackTrace.from_json(json['stackTrace']) if 'stackTrace' in json else None,
        )


def enable() -> typing.Generator[T_JSON_DICT,T_JSON_DICT,None]:
    '''
    Enables the WebMCP domain, allowing events to be sent. Enabling the domain will trigger a toolsAdded event for
    all currently registered tools.
    '''
    cmd_dict: T_JSON_DICT = {
        'method': 'WebMCP.enable',
    }
    json = yield cmd_dict


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


@event_class('WebMCP.toolsAdded')
@dataclass
class ToolsAdded:
    '''
    Event fired when new tools are added.
    '''
    #: Array of tools that were added.
    tools: typing.List[Tool]

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ToolsAdded:
        return cls(
            tools=[Tool.from_json(i) for i in json['tools']]
        )


@event_class('WebMCP.toolsRemoved')
@dataclass
class ToolsRemoved:
    '''
    Event fired when tools are removed.
    '''
    #: Array of tools that were removed.
    tools: typing.List[Tool]

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ToolsRemoved:
        return cls(
            tools=[Tool.from_json(i) for i in json['tools']]
        )


@event_class('WebMCP.toolInvoked')
@dataclass
class ToolInvoked:
    '''
    Event fired when a tool invocation starts.
    '''
    #: Name of the tool to invoke.
    tool_name: str
    #: Frame id
    frame_id: page.FrameId
    #: Invocation identifier.
    invocation_id: str
    #: The input parameters used for the invocation.
    input_: str

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ToolInvoked:
        return cls(
            tool_name=str(json['toolName']),
            frame_id=page.FrameId.from_json(json['frameId']),
            invocation_id=str(json['invocationId']),
            input_=str(json['input'])
        )


@event_class('WebMCP.toolResponded')
@dataclass
class ToolResponded:
    '''
    Event fired when a tool invocation completes or fails.
    '''
    #: Invocation identifier.
    invocation_id: str
    #: Status of the invocation.
    status: InvocationStatus
    #: Output or error delivered as delivered to the agent. Missing if ``status`` is anything other than Success.
    output: typing.Optional[typing.Any]
    #: Error text for protocol users.
    error_text: typing.Optional[str]
    #: The exception object, if the javascript tool threw an error>
    exception: typing.Optional[runtime.RemoteObject]

    @classmethod
    def from_json(cls, json: T_JSON_DICT) -> ToolResponded:
        return cls(
            invocation_id=str(json['invocationId']),
            status=InvocationStatus.from_json(json['status']),
            output=json['output'] if 'output' in json else None,
            error_text=str(json['errorText']) if 'errorText' in json else None,
            exception=runtime.RemoteObject.from_json(json['exception']) if 'exception' in json else None
        )
