1#!/usr/bin/env python3
2# -*- coding: utf-8 -*-
3"""
4Copyright (c) 2024 Huawei Device Co., Ltd.
5Licensed under the Apache License, Version 2.0 (the "License");
6you may not use this file except in compliance with the License.
7You may obtain a copy of the License at
8
9    http://www.apache.org/licenses/LICENSE-2.0
10
11Unless required by applicable law or agreed to in writing, software
12distributed under the License is distributed on an "AS IS" BASIS,
13WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14See the License for the specific language governing permissions and
15limitations under the License.
16
17Description: Python CDP Debugger.
18"""
19
20from dataclasses import dataclass, field
21from enum import Enum
22from typing import Optional, List
23
24
25@dataclass
26class DropFrameParams:
27    dropped_depth: int = 1
28
29
30@dataclass
31class ReplyNativeCallingParams:
32    user_code: bool = True
33
34
35@dataclass
36class SetMixedDebugEnabledParams:
37    enabled: bool
38    mixed_stack_enabled: bool
39
40
41@dataclass
42class SmartStepIntoParams:
43    url: str
44    line_number: int
45
46
47@dataclass
48class PauseOnExceptionsState(Enum):
49    ALL = 'all'
50    NONE = 'none'
51    CAUGHT = 'caught'
52    UNCAUGHT = 'uncaught'
53
54
55@dataclass
56class EvaluateOnCallFrameParams:
57    expression: str
58    call_frame_id: int = 0
59    object_group: str = "console"
60    include_command_line_api: bool = True
61    silent: bool = True
62
63
64@dataclass
65class BreakLocationUrl:
66    url: str
67    line_number: int
68    column_number: Optional[int] = 0
69    condition: Optional[str] = None
70
71    def to_json(self):
72        json = {'url': self.url,
73                'lineNumber': self.line_number,
74                'columnNumber': self.column_number}
75        if self.condition is not None:
76            json['condition'] = self.condition
77        return json
78
79
80@dataclass
81class RemoveBreakpointsUrl:
82    url: str = ""
83
84
85@dataclass
86class SetBreakpointsLocations:
87    locations: list = field(default_factory=list)
88
89
90def enable():
91    command = {'method': 'Debugger.enable'}
92    return command
93
94
95def resume():
96    command = {'method': 'Debugger.resume'}
97    return command
98
99
100def remove_breakpoints_by_url(params: RemoveBreakpointsUrl):
101    command = {'method': 'Debugger.removeBreakpointsByUrl',
102               'params': {'url': params.url}}
103    return command
104
105
106def get_possible_and_set_breakpoint_by_url(params: SetBreakpointsLocations):
107    locations = []
108    for location in params.locations:
109        locations.append(location.to_json())
110    command = {'method': 'Debugger.getPossibleAndSetBreakpointByUrl',
111               'params': {'locations': locations}}
112    return command
113
114
115def step_over():
116    command = {'method': 'Debugger.stepOver'}
117    return command
118
119
120def step_into():
121    command = {'method': 'Debugger.stepInto'}
122    return command
123
124
125def step_out():
126    command = {'method': 'Debugger.stepOut'}
127    return command
128
129
130def disable():
131    command = {'method': 'Debugger.disable'}
132    return command
133
134
135def set_pause_on_exceptions(params: PauseOnExceptionsState):
136    command = {'method': 'Debugger.setPauseOnExceptions',
137               'params': {'state': params.value}}
138    return command
139
140
141def evaluate_on_call_frame(params: EvaluateOnCallFrameParams):
142    command = {'method': 'Debugger.evaluateOnCallFrame',
143               'params': {
144                   'callFrameId': str(params.call_frame_id),
145                   'expression': params.expression,
146                   'includeCommandLineApi': params.include_command_line_api,
147                   'objectGroup': params.object_group,
148                   'silent': params.silent}}
149    return command
150
151
152def pause():
153    command = {'method': 'Debugger.pause'}
154    return command
155
156
157def set_mixed_debug_enabled(params: SetMixedDebugEnabledParams):
158    command = {'method': 'Debugger.setMixedDebugEnabled',
159               'params': {'enabled': params.enabled, 'mixedStackEnabled': params.mixed_stack_enabled}}
160    return command
161
162
163def reply_native_calling(params: ReplyNativeCallingParams):
164    command = {'method': 'Debugger.replyNativeCalling',
165               'params': {'userCode': params.user_code}}
166    return command
167
168
169def drop_frame(params: DropFrameParams):
170    command = {'method': 'Debugger.dropFrame',
171               'params': {'droppedDepth': params.dropped_depth}}
172    return command
173
174
175def smart_step_into(params: SmartStepIntoParams):
176    command = {'method': 'Debugger.smartStepInto',
177               'params': {'url': params.url, 'lineNumber': params.line_number}}
178    return command