// Package dom provides the Chrome DevTools Protocol
// commands, types, and events for the DOM domain.
//
// This domain exposes DOM read/write operations. Each DOM Node is
// represented with its mirror object that has an id. This id can be used to get
// additional information on the Node, resolve it into the JavaScript object
// wrapper, etc. It is important that client receives DOM events only for the
// nodes that are known to the client. Backend keeps track of the nodes that
// were sent to the client and never sends the same node twice. It is client's
// responsibility to collect information about the nodes that were sent to the
// client.
//
// Note that iframe owner elements will return corresponding document
// elements as their child nodes.
//
// Generated by the cdproto-gen command.
package dom

// Code generated by cdproto-gen. DO NOT EDIT.

import (
	"context"

	"github.com/chromedp/cdproto/cdp"
	"github.com/chromedp/cdproto/runtime"
)

// CollectClassNamesFromSubtreeParams collects class names for the node with
// given id and all of it's child nodes.
type CollectClassNamesFromSubtreeParams struct {
	NodeID cdp.NodeID `json:"nodeId"` // Id of the node to collect class names.
}

// CollectClassNamesFromSubtree collects class names for the node with given
// id and all of it's child nodes.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-collectClassNamesFromSubtree
//
// parameters:
//
//	nodeID - Id of the node to collect class names.
func CollectClassNamesFromSubtree(nodeID cdp.NodeID) *CollectClassNamesFromSubtreeParams {
	return &CollectClassNamesFromSubtreeParams{
		NodeID: nodeID,
	}
}

// CollectClassNamesFromSubtreeReturns return values.
type CollectClassNamesFromSubtreeReturns struct {
	ClassNames []string `json:"classNames,omitempty"` // Class name list.
}

// Do executes DOM.collectClassNamesFromSubtree against the provided context.
//
// returns:
//
//	classNames - Class name list.
func (p *CollectClassNamesFromSubtreeParams) Do(ctx context.Context) (classNames []string, err error) {
	// execute
	var res CollectClassNamesFromSubtreeReturns
	err = cdp.Execute(ctx, CommandCollectClassNamesFromSubtree, p, &res)
	if err != nil {
		return nil, err
	}

	return res.ClassNames, nil
}

// CopyToParams creates a deep copy of the specified node and places it into
// the target container before the given anchor.
type CopyToParams struct {
	NodeID             cdp.NodeID `json:"nodeId"`                       // Id of the node to copy.
	TargetNodeID       cdp.NodeID `json:"targetNodeId"`                 // Id of the element to drop the copy into.
	InsertBeforeNodeID cdp.NodeID `json:"insertBeforeNodeId,omitempty"` // Drop the copy before this node (if absent, the copy becomes the last child of targetNodeId).
}

// CopyTo creates a deep copy of the specified node and places it into the
// target container before the given anchor.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-copyTo
//
// parameters:
//
//	nodeID - Id of the node to copy.
//	targetNodeID - Id of the element to drop the copy into.
func CopyTo(nodeID cdp.NodeID, targetNodeID cdp.NodeID) *CopyToParams {
	return &CopyToParams{
		NodeID:       nodeID,
		TargetNodeID: targetNodeID,
	}
}

// WithInsertBeforeNodeID drop the copy before this node (if absent, the copy
// becomes the last child of targetNodeId).
func (p CopyToParams) WithInsertBeforeNodeID(insertBeforeNodeID cdp.NodeID) *CopyToParams {
	p.InsertBeforeNodeID = insertBeforeNodeID
	return &p
}

// CopyToReturns return values.
type CopyToReturns struct {
	NodeID cdp.NodeID `json:"nodeId,omitempty"` // Id of the node clone.
}

// Do executes DOM.copyTo against the provided context.
//
// returns:
//
//	nodeID - Id of the node clone.
func (p *CopyToParams) Do(ctx context.Context) (nodeID cdp.NodeID, err error) {
	// execute
	var res CopyToReturns
	err = cdp.Execute(ctx, CommandCopyTo, p, &res)
	if err != nil {
		return 0, err
	}

	return res.NodeID, nil
}

// DescribeNodeParams describes node given its id, does not require domain to
// be enabled. Does not start tracking any objects, can be used for automation.
type DescribeNodeParams struct {
	NodeID        cdp.NodeID             `json:"nodeId,omitempty"`        // Identifier of the node.
	BackendNodeID cdp.BackendNodeID      `json:"backendNodeId,omitempty"` // Identifier of the backend node.
	ObjectID      runtime.RemoteObjectID `json:"objectId,omitempty"`      // JavaScript object id of the node wrapper.
	Depth         int64                  `json:"depth,omitempty"`         // The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0.
	Pierce        bool                   `json:"pierce,omitempty"`        // Whether or not iframes and shadow roots should be traversed when returning the subtree (default is false).
}

// DescribeNode describes node given its id, does not require domain to be
// enabled. Does not start tracking any objects, can be used for automation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-describeNode
//
// parameters:
func DescribeNode() *DescribeNodeParams {
	return &DescribeNodeParams{}
}

// WithNodeID identifier of the node.
func (p DescribeNodeParams) WithNodeID(nodeID cdp.NodeID) *DescribeNodeParams {
	p.NodeID = nodeID
	return &p
}

// WithBackendNodeID identifier of the backend node.
func (p DescribeNodeParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *DescribeNodeParams {
	p.BackendNodeID = backendNodeID
	return &p
}

// WithObjectID JavaScript object id of the node wrapper.
func (p DescribeNodeParams) WithObjectID(objectID runtime.RemoteObjectID) *DescribeNodeParams {
	p.ObjectID = objectID
	return &p
}

// WithDepth the maximum depth at which children should be retrieved,
// defaults to 1. Use -1 for the entire subtree or provide an integer larger
// than 0.
func (p DescribeNodeParams) WithDepth(depth int64) *DescribeNodeParams {
	p.Depth = depth
	return &p
}

// WithPierce whether or not iframes and shadow roots should be traversed
// when returning the subtree (default is false).
func (p DescribeNodeParams) WithPierce(pierce bool) *DescribeNodeParams {
	p.Pierce = pierce
	return &p
}

// DescribeNodeReturns return values.
type DescribeNodeReturns struct {
	Node *cdp.Node `json:"node,omitempty"` // Node description.
}

// Do executes DOM.describeNode against the provided context.
//
// returns:
//
//	node - Node description.
func (p *DescribeNodeParams) Do(ctx context.Context) (node *cdp.Node, err error) {
	// execute
	var res DescribeNodeReturns
	err = cdp.Execute(ctx, CommandDescribeNode, p, &res)
	if err != nil {
		return nil, err
	}

	return res.Node, nil
}

// ScrollIntoViewIfNeededParams scrolls the specified rect of the given node
// into view if not already visible. Note: exactly one between nodeId,
// backendNodeId and objectId should be passed to identify the node.
type ScrollIntoViewIfNeededParams struct {
	NodeID        cdp.NodeID             `json:"nodeId,omitempty"`        // Identifier of the node.
	BackendNodeID cdp.BackendNodeID      `json:"backendNodeId,omitempty"` // Identifier of the backend node.
	ObjectID      runtime.RemoteObjectID `json:"objectId,omitempty"`      // JavaScript object id of the node wrapper.
	Rect          *Rect                  `json:"rect,omitempty"`          // The rect to be scrolled into view, relative to the node's border box, in CSS pixels. When omitted, center of the node will be used, similar to Element.scrollIntoView.
}

// ScrollIntoViewIfNeeded scrolls the specified rect of the given node into
// view if not already visible. Note: exactly one between nodeId, backendNodeId
// and objectId should be passed to identify the node.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-scrollIntoViewIfNeeded
//
// parameters:
func ScrollIntoViewIfNeeded() *ScrollIntoViewIfNeededParams {
	return &ScrollIntoViewIfNeededParams{}
}

// WithNodeID identifier of the node.
func (p ScrollIntoViewIfNeededParams) WithNodeID(nodeID cdp.NodeID) *ScrollIntoViewIfNeededParams {
	p.NodeID = nodeID
	return &p
}

// WithBackendNodeID identifier of the backend node.
func (p ScrollIntoViewIfNeededParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *ScrollIntoViewIfNeededParams {
	p.BackendNodeID = backendNodeID
	return &p
}

// WithObjectID JavaScript object id of the node wrapper.
func (p ScrollIntoViewIfNeededParams) WithObjectID(objectID runtime.RemoteObjectID) *ScrollIntoViewIfNeededParams {
	p.ObjectID = objectID
	return &p
}

// WithRect the rect to be scrolled into view, relative to the node's border
// box, in CSS pixels. When omitted, center of the node will be used, similar to
// Element.scrollIntoView.
func (p ScrollIntoViewIfNeededParams) WithRect(rect *Rect) *ScrollIntoViewIfNeededParams {
	p.Rect = rect
	return &p
}

// Do executes DOM.scrollIntoViewIfNeeded against the provided context.
func (p *ScrollIntoViewIfNeededParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandScrollIntoViewIfNeeded, p, nil)
}

// DisableParams disables DOM agent for the given page.
type DisableParams struct{}

// Disable disables DOM agent for the given page.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-disable
func Disable() *DisableParams {
	return &DisableParams{}
}

// Do executes DOM.disable against the provided context.
func (p *DisableParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandDisable, nil, nil)
}

// DiscardSearchResultsParams discards search results from the session with
// the given id. getSearchResults should no longer be called for that search.
type DiscardSearchResultsParams struct {
	SearchID string `json:"searchId"` // Unique search session identifier.
}

// DiscardSearchResults discards search results from the session with the
// given id. getSearchResults should no longer be called for that search.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-discardSearchResults
//
// parameters:
//
//	searchID - Unique search session identifier.
func DiscardSearchResults(searchID string) *DiscardSearchResultsParams {
	return &DiscardSearchResultsParams{
		SearchID: searchID,
	}
}

// Do executes DOM.discardSearchResults against the provided context.
func (p *DiscardSearchResultsParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandDiscardSearchResults, p, nil)
}

// EnableParams enables DOM agent for the given page.
type EnableParams struct {
	IncludeWhitespace EnableIncludeWhitespace `json:"includeWhitespace,omitempty"` // Whether to include whitespaces in the children array of returned Nodes.
}

// Enable enables DOM agent for the given page.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-enable
//
// parameters:
func Enable() *EnableParams {
	return &EnableParams{}
}

// WithIncludeWhitespace whether to include whitespaces in the children array
// of returned Nodes.
func (p EnableParams) WithIncludeWhitespace(includeWhitespace EnableIncludeWhitespace) *EnableParams {
	p.IncludeWhitespace = includeWhitespace
	return &p
}

// Do executes DOM.enable against the provided context.
func (p *EnableParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandEnable, p, nil)
}

// FocusParams focuses the given element.
type FocusParams struct {
	NodeID        cdp.NodeID             `json:"nodeId,omitempty"`        // Identifier of the node.
	BackendNodeID cdp.BackendNodeID      `json:"backendNodeId,omitempty"` // Identifier of the backend node.
	ObjectID      runtime.RemoteObjectID `json:"objectId,omitempty"`      // JavaScript object id of the node wrapper.
}

// Focus focuses the given element.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-focus
//
// parameters:
func Focus() *FocusParams {
	return &FocusParams{}
}

// WithNodeID identifier of the node.
func (p FocusParams) WithNodeID(nodeID cdp.NodeID) *FocusParams {
	p.NodeID = nodeID
	return &p
}

// WithBackendNodeID identifier of the backend node.
func (p FocusParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *FocusParams {
	p.BackendNodeID = backendNodeID
	return &p
}

// WithObjectID JavaScript object id of the node wrapper.
func (p FocusParams) WithObjectID(objectID runtime.RemoteObjectID) *FocusParams {
	p.ObjectID = objectID
	return &p
}

// Do executes DOM.focus against the provided context.
func (p *FocusParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandFocus, p, nil)
}

// GetAttributesParams returns attributes for the specified node.
type GetAttributesParams struct {
	NodeID cdp.NodeID `json:"nodeId"` // Id of the node to retrieve attibutes for.
}

// GetAttributes returns attributes for the specified node.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getAttributes
//
// parameters:
//
//	nodeID - Id of the node to retrieve attibutes for.
func GetAttributes(nodeID cdp.NodeID) *GetAttributesParams {
	return &GetAttributesParams{
		NodeID: nodeID,
	}
}

// GetAttributesReturns return values.
type GetAttributesReturns struct {
	Attributes []string `json:"attributes,omitempty"` // An interleaved array of node attribute names and values.
}

// Do executes DOM.getAttributes against the provided context.
//
// returns:
//
//	attributes - An interleaved array of node attribute names and values.
func (p *GetAttributesParams) Do(ctx context.Context) (attributes []string, err error) {
	// execute
	var res GetAttributesReturns
	err = cdp.Execute(ctx, CommandGetAttributes, p, &res)
	if err != nil {
		return nil, err
	}

	return res.Attributes, nil
}

// GetBoxModelParams returns boxes for the given node.
type GetBoxModelParams struct {
	NodeID        cdp.NodeID             `json:"nodeId,omitempty"`        // Identifier of the node.
	BackendNodeID cdp.BackendNodeID      `json:"backendNodeId,omitempty"` // Identifier of the backend node.
	ObjectID      runtime.RemoteObjectID `json:"objectId,omitempty"`      // JavaScript object id of the node wrapper.
}

// GetBoxModel returns boxes for the given node.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getBoxModel
//
// parameters:
func GetBoxModel() *GetBoxModelParams {
	return &GetBoxModelParams{}
}

// WithNodeID identifier of the node.
func (p GetBoxModelParams) WithNodeID(nodeID cdp.NodeID) *GetBoxModelParams {
	p.NodeID = nodeID
	return &p
}

// WithBackendNodeID identifier of the backend node.
func (p GetBoxModelParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *GetBoxModelParams {
	p.BackendNodeID = backendNodeID
	return &p
}

// WithObjectID JavaScript object id of the node wrapper.
func (p GetBoxModelParams) WithObjectID(objectID runtime.RemoteObjectID) *GetBoxModelParams {
	p.ObjectID = objectID
	return &p
}

// GetBoxModelReturns return values.
type GetBoxModelReturns struct {
	Model *BoxModel `json:"model,omitempty"` // Box model for the node.
}

// Do executes DOM.getBoxModel against the provided context.
//
// returns:
//
//	model - Box model for the node.
func (p *GetBoxModelParams) Do(ctx context.Context) (model *BoxModel, err error) {
	// execute
	var res GetBoxModelReturns
	err = cdp.Execute(ctx, CommandGetBoxModel, p, &res)
	if err != nil {
		return nil, err
	}

	return res.Model, nil
}

// GetContentQuadsParams returns quads that describe node position on the
// page. This method might return multiple quads for inline nodes.
type GetContentQuadsParams struct {
	NodeID        cdp.NodeID             `json:"nodeId,omitempty"`        // Identifier of the node.
	BackendNodeID cdp.BackendNodeID      `json:"backendNodeId,omitempty"` // Identifier of the backend node.
	ObjectID      runtime.RemoteObjectID `json:"objectId,omitempty"`      // JavaScript object id of the node wrapper.
}

// GetContentQuads returns quads that describe node position on the page.
// This method might return multiple quads for inline nodes.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getContentQuads
//
// parameters:
func GetContentQuads() *GetContentQuadsParams {
	return &GetContentQuadsParams{}
}

// WithNodeID identifier of the node.
func (p GetContentQuadsParams) WithNodeID(nodeID cdp.NodeID) *GetContentQuadsParams {
	p.NodeID = nodeID
	return &p
}

// WithBackendNodeID identifier of the backend node.
func (p GetContentQuadsParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *GetContentQuadsParams {
	p.BackendNodeID = backendNodeID
	return &p
}

// WithObjectID JavaScript object id of the node wrapper.
func (p GetContentQuadsParams) WithObjectID(objectID runtime.RemoteObjectID) *GetContentQuadsParams {
	p.ObjectID = objectID
	return &p
}

// GetContentQuadsReturns return values.
type GetContentQuadsReturns struct {
	Quads []Quad `json:"quads,omitempty"` // Quads that describe node layout relative to viewport.
}

// Do executes DOM.getContentQuads against the provided context.
//
// returns:
//
//	quads - Quads that describe node layout relative to viewport.
func (p *GetContentQuadsParams) Do(ctx context.Context) (quads []Quad, err error) {
	// execute
	var res GetContentQuadsReturns
	err = cdp.Execute(ctx, CommandGetContentQuads, p, &res)
	if err != nil {
		return nil, err
	}

	return res.Quads, nil
}

// GetDocumentParams returns the root DOM node (and optionally the subtree)
// to the caller. Implicitly enables the DOM domain events for the current
// target.
type GetDocumentParams struct {
	Depth  int64 `json:"depth,omitempty"`  // The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0.
	Pierce bool  `json:"pierce,omitempty"` // Whether or not iframes and shadow roots should be traversed when returning the subtree (default is false).
}

// GetDocument returns the root DOM node (and optionally the subtree) to the
// caller. Implicitly enables the DOM domain events for the current target.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getDocument
//
// parameters:
func GetDocument() *GetDocumentParams {
	return &GetDocumentParams{}
}

// WithDepth the maximum depth at which children should be retrieved,
// defaults to 1. Use -1 for the entire subtree or provide an integer larger
// than 0.
func (p GetDocumentParams) WithDepth(depth int64) *GetDocumentParams {
	p.Depth = depth
	return &p
}

// WithPierce whether or not iframes and shadow roots should be traversed
// when returning the subtree (default is false).
func (p GetDocumentParams) WithPierce(pierce bool) *GetDocumentParams {
	p.Pierce = pierce
	return &p
}

// GetDocumentReturns return values.
type GetDocumentReturns struct {
	Root *cdp.Node `json:"root,omitempty"` // Resulting node.
}

// Do executes DOM.getDocument against the provided context.
//
// returns:
//
//	root - Resulting node.
func (p *GetDocumentParams) Do(ctx context.Context) (root *cdp.Node, err error) {
	// execute
	var res GetDocumentReturns
	err = cdp.Execute(ctx, CommandGetDocument, p, &res)
	if err != nil {
		return nil, err
	}

	return res.Root, nil
}

// GetNodesForSubtreeByStyleParams finds nodes with a given computed style in
// a subtree.
type GetNodesForSubtreeByStyleParams struct {
	NodeID         cdp.NodeID                  `json:"nodeId"`           // Node ID pointing to the root of a subtree.
	ComputedStyles []*CSSComputedStyleProperty `json:"computedStyles"`   // The style to filter nodes by (includes nodes if any of properties matches).
	Pierce         bool                        `json:"pierce,omitempty"` // Whether or not iframes and shadow roots in the same target should be traversed when returning the results (default is false).
}

// GetNodesForSubtreeByStyle finds nodes with a given computed style in a
// subtree.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getNodesForSubtreeByStyle
//
// parameters:
//
//	nodeID - Node ID pointing to the root of a subtree.
//	computedStyles - The style to filter nodes by (includes nodes if any of properties matches).
func GetNodesForSubtreeByStyle(nodeID cdp.NodeID, computedStyles []*CSSComputedStyleProperty) *GetNodesForSubtreeByStyleParams {
	return &GetNodesForSubtreeByStyleParams{
		NodeID:         nodeID,
		ComputedStyles: computedStyles,
	}
}

// WithPierce whether or not iframes and shadow roots in the same target
// should be traversed when returning the results (default is false).
func (p GetNodesForSubtreeByStyleParams) WithPierce(pierce bool) *GetNodesForSubtreeByStyleParams {
	p.Pierce = pierce
	return &p
}

// GetNodesForSubtreeByStyleReturns return values.
type GetNodesForSubtreeByStyleReturns struct {
	NodeIDs []cdp.NodeID `json:"nodeIds,omitempty"` // Resulting nodes.
}

// Do executes DOM.getNodesForSubtreeByStyle against the provided context.
//
// returns:
//
//	nodeIDs - Resulting nodes.
func (p *GetNodesForSubtreeByStyleParams) Do(ctx context.Context) (nodeIDs []cdp.NodeID, err error) {
	// execute
	var res GetNodesForSubtreeByStyleReturns
	err = cdp.Execute(ctx, CommandGetNodesForSubtreeByStyle, p, &res)
	if err != nil {
		return nil, err
	}

	return res.NodeIDs, nil
}

// GetNodeForLocationParams returns node id at given location. Depending on
// whether DOM domain is enabled, nodeId is either returned or not.
type GetNodeForLocationParams struct {
	X                         int64 `json:"x"`                                   // X coordinate.
	Y                         int64 `json:"y"`                                   // Y coordinate.
	IncludeUserAgentShadowDOM bool  `json:"includeUserAgentShadowDOM,omitempty"` // False to skip to the nearest non-UA shadow root ancestor (default: false).
	IgnorePointerEventsNone   bool  `json:"ignorePointerEventsNone,omitempty"`   // Whether to ignore pointer-events: none on elements and hit test them.
}

// GetNodeForLocation returns node id at given location. Depending on whether
// DOM domain is enabled, nodeId is either returned or not.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getNodeForLocation
//
// parameters:
//
//	x - X coordinate.
//	y - Y coordinate.
func GetNodeForLocation(x int64, y int64) *GetNodeForLocationParams {
	return &GetNodeForLocationParams{
		X: x,
		Y: y,
	}
}

// WithIncludeUserAgentShadowDOM false to skip to the nearest non-UA shadow
// root ancestor (default: false).
func (p GetNodeForLocationParams) WithIncludeUserAgentShadowDOM(includeUserAgentShadowDOM bool) *GetNodeForLocationParams {
	p.IncludeUserAgentShadowDOM = includeUserAgentShadowDOM
	return &p
}

// WithIgnorePointerEventsNone whether to ignore pointer-events: none on
// elements and hit test them.
func (p GetNodeForLocationParams) WithIgnorePointerEventsNone(ignorePointerEventsNone bool) *GetNodeForLocationParams {
	p.IgnorePointerEventsNone = ignorePointerEventsNone
	return &p
}

// GetNodeForLocationReturns return values.
type GetNodeForLocationReturns struct {
	BackendNodeID cdp.BackendNodeID `json:"backendNodeId,omitempty"` // Resulting node.
	FrameID       cdp.FrameID       `json:"frameId,omitempty"`       // Frame this node belongs to.
	NodeID        cdp.NodeID        `json:"nodeId,omitempty"`        // Id of the node at given coordinates, only when enabled and requested document.
}

// Do executes DOM.getNodeForLocation against the provided context.
//
// returns:
//
//	backendNodeID - Resulting node.
//	frameID - Frame this node belongs to.
//	nodeID - Id of the node at given coordinates, only when enabled and requested document.
func (p *GetNodeForLocationParams) Do(ctx context.Context) (backendNodeID cdp.BackendNodeID, frameID cdp.FrameID, nodeID cdp.NodeID, err error) {
	// execute
	var res GetNodeForLocationReturns
	err = cdp.Execute(ctx, CommandGetNodeForLocation, p, &res)
	if err != nil {
		return 0, "", 0, err
	}

	return res.BackendNodeID, res.FrameID, res.NodeID, nil
}

// GetOuterHTMLParams returns node's HTML markup.
type GetOuterHTMLParams struct {
	NodeID        cdp.NodeID             `json:"nodeId,omitempty"`        // Identifier of the node.
	BackendNodeID cdp.BackendNodeID      `json:"backendNodeId,omitempty"` // Identifier of the backend node.
	ObjectID      runtime.RemoteObjectID `json:"objectId,omitempty"`      // JavaScript object id of the node wrapper.
}

// GetOuterHTML returns node's HTML markup.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getOuterHTML
//
// parameters:
func GetOuterHTML() *GetOuterHTMLParams {
	return &GetOuterHTMLParams{}
}

// WithNodeID identifier of the node.
func (p GetOuterHTMLParams) WithNodeID(nodeID cdp.NodeID) *GetOuterHTMLParams {
	p.NodeID = nodeID
	return &p
}

// WithBackendNodeID identifier of the backend node.
func (p GetOuterHTMLParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *GetOuterHTMLParams {
	p.BackendNodeID = backendNodeID
	return &p
}

// WithObjectID JavaScript object id of the node wrapper.
func (p GetOuterHTMLParams) WithObjectID(objectID runtime.RemoteObjectID) *GetOuterHTMLParams {
	p.ObjectID = objectID
	return &p
}

// GetOuterHTMLReturns return values.
type GetOuterHTMLReturns struct {
	OuterHTML string `json:"outerHTML,omitempty"` // Outer HTML markup.
}

// Do executes DOM.getOuterHTML against the provided context.
//
// returns:
//
//	outerHTML - Outer HTML markup.
func (p *GetOuterHTMLParams) Do(ctx context.Context) (outerHTML string, err error) {
	// execute
	var res GetOuterHTMLReturns
	err = cdp.Execute(ctx, CommandGetOuterHTML, p, &res)
	if err != nil {
		return "", err
	}

	return res.OuterHTML, nil
}

// GetRelayoutBoundaryParams returns the id of the nearest ancestor that is a
// relayout boundary.
type GetRelayoutBoundaryParams struct {
	NodeID cdp.NodeID `json:"nodeId"` // Id of the node.
}

// GetRelayoutBoundary returns the id of the nearest ancestor that is a
// relayout boundary.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getRelayoutBoundary
//
// parameters:
//
//	nodeID - Id of the node.
func GetRelayoutBoundary(nodeID cdp.NodeID) *GetRelayoutBoundaryParams {
	return &GetRelayoutBoundaryParams{
		NodeID: nodeID,
	}
}

// GetRelayoutBoundaryReturns return values.
type GetRelayoutBoundaryReturns struct {
	NodeID cdp.NodeID `json:"nodeId,omitempty"` // Relayout boundary node id for the given node.
}

// Do executes DOM.getRelayoutBoundary against the provided context.
//
// returns:
//
//	nodeID - Relayout boundary node id for the given node.
func (p *GetRelayoutBoundaryParams) Do(ctx context.Context) (nodeID cdp.NodeID, err error) {
	// execute
	var res GetRelayoutBoundaryReturns
	err = cdp.Execute(ctx, CommandGetRelayoutBoundary, p, &res)
	if err != nil {
		return 0, err
	}

	return res.NodeID, nil
}

// GetSearchResultsParams returns search results from given fromIndex to
// given toIndex from the search with the given identifier.
type GetSearchResultsParams struct {
	SearchID  string `json:"searchId"`  // Unique search session identifier.
	FromIndex int64  `json:"fromIndex"` // Start index of the search result to be returned.
	ToIndex   int64  `json:"toIndex"`   // End index of the search result to be returned.
}

// GetSearchResults returns search results from given fromIndex to given
// toIndex from the search with the given identifier.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getSearchResults
//
// parameters:
//
//	searchID - Unique search session identifier.
//	fromIndex - Start index of the search result to be returned.
//	toIndex - End index of the search result to be returned.
func GetSearchResults(searchID string, fromIndex int64, toIndex int64) *GetSearchResultsParams {
	return &GetSearchResultsParams{
		SearchID:  searchID,
		FromIndex: fromIndex,
		ToIndex:   toIndex,
	}
}

// GetSearchResultsReturns return values.
type GetSearchResultsReturns struct {
	NodeIDs []cdp.NodeID `json:"nodeIds,omitempty"` // Ids of the search result nodes.
}

// Do executes DOM.getSearchResults against the provided context.
//
// returns:
//
//	nodeIDs - Ids of the search result nodes.
func (p *GetSearchResultsParams) Do(ctx context.Context) (nodeIDs []cdp.NodeID, err error) {
	// execute
	var res GetSearchResultsReturns
	err = cdp.Execute(ctx, CommandGetSearchResults, p, &res)
	if err != nil {
		return nil, err
	}

	return res.NodeIDs, nil
}

// MarkUndoableStateParams marks last undoable state.
type MarkUndoableStateParams struct{}

// MarkUndoableState marks last undoable state.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-markUndoableState
func MarkUndoableState() *MarkUndoableStateParams {
	return &MarkUndoableStateParams{}
}

// Do executes DOM.markUndoableState against the provided context.
func (p *MarkUndoableStateParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandMarkUndoableState, nil, nil)
}

// MoveToParams moves node into the new container, places it before the given
// anchor.
type MoveToParams struct {
	NodeID             cdp.NodeID `json:"nodeId"`                       // Id of the node to move.
	TargetNodeID       cdp.NodeID `json:"targetNodeId"`                 // Id of the element to drop the moved node into.
	InsertBeforeNodeID cdp.NodeID `json:"insertBeforeNodeId,omitempty"` // Drop node before this one (if absent, the moved node becomes the last child of targetNodeId).
}

// MoveTo moves node into the new container, places it before the given
// anchor.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-moveTo
//
// parameters:
//
//	nodeID - Id of the node to move.
//	targetNodeID - Id of the element to drop the moved node into.
func MoveTo(nodeID cdp.NodeID, targetNodeID cdp.NodeID) *MoveToParams {
	return &MoveToParams{
		NodeID:       nodeID,
		TargetNodeID: targetNodeID,
	}
}

// WithInsertBeforeNodeID drop node before this one (if absent, the moved
// node becomes the last child of targetNodeId).
func (p MoveToParams) WithInsertBeforeNodeID(insertBeforeNodeID cdp.NodeID) *MoveToParams {
	p.InsertBeforeNodeID = insertBeforeNodeID
	return &p
}

// MoveToReturns return values.
type MoveToReturns struct {
	NodeID cdp.NodeID `json:"nodeId,omitempty"` // New id of the moved node.
}

// Do executes DOM.moveTo against the provided context.
//
// returns:
//
//	nodeID - New id of the moved node.
func (p *MoveToParams) Do(ctx context.Context) (nodeID cdp.NodeID, err error) {
	// execute
	var res MoveToReturns
	err = cdp.Execute(ctx, CommandMoveTo, p, &res)
	if err != nil {
		return 0, err
	}

	return res.NodeID, nil
}

// PerformSearchParams searches for a given string in the DOM tree. Use
// getSearchResults to access search results or cancelSearch to end this search
// session.
type PerformSearchParams struct {
	Query                     string `json:"query"`                               // Plain text or query selector or XPath search query.
	IncludeUserAgentShadowDOM bool   `json:"includeUserAgentShadowDOM,omitempty"` // True to search in user agent shadow DOM.
}

// PerformSearch searches for a given string in the DOM tree. Use
// getSearchResults to access search results or cancelSearch to end this search
// session.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-performSearch
//
// parameters:
//
//	query - Plain text or query selector or XPath search query.
func PerformSearch(query string) *PerformSearchParams {
	return &PerformSearchParams{
		Query: query,
	}
}

// WithIncludeUserAgentShadowDOM true to search in user agent shadow DOM.
func (p PerformSearchParams) WithIncludeUserAgentShadowDOM(includeUserAgentShadowDOM bool) *PerformSearchParams {
	p.IncludeUserAgentShadowDOM = includeUserAgentShadowDOM
	return &p
}

// PerformSearchReturns return values.
type PerformSearchReturns struct {
	SearchID    string `json:"searchId,omitempty"`    // Unique search session identifier.
	ResultCount int64  `json:"resultCount,omitempty"` // Number of search results.
}

// Do executes DOM.performSearch against the provided context.
//
// returns:
//
//	searchID - Unique search session identifier.
//	resultCount - Number of search results.
func (p *PerformSearchParams) Do(ctx context.Context) (searchID string, resultCount int64, err error) {
	// execute
	var res PerformSearchReturns
	err = cdp.Execute(ctx, CommandPerformSearch, p, &res)
	if err != nil {
		return "", 0, err
	}

	return res.SearchID, res.ResultCount, nil
}

// PushNodeByPathToFrontendParams requests that the node is sent to the
// caller given its path. // FIXME, use XPath.
type PushNodeByPathToFrontendParams struct {
	Path string `json:"path"` // Path to node in the proprietary format.
}

// PushNodeByPathToFrontend requests that the node is sent to the caller
// given its path. // FIXME, use XPath.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-pushNodeByPathToFrontend
//
// parameters:
//
//	path - Path to node in the proprietary format.
func PushNodeByPathToFrontend(path string) *PushNodeByPathToFrontendParams {
	return &PushNodeByPathToFrontendParams{
		Path: path,
	}
}

// PushNodeByPathToFrontendReturns return values.
type PushNodeByPathToFrontendReturns struct {
	NodeID cdp.NodeID `json:"nodeId,omitempty"` // Id of the node for given path.
}

// Do executes DOM.pushNodeByPathToFrontend against the provided context.
//
// returns:
//
//	nodeID - Id of the node for given path.
func (p *PushNodeByPathToFrontendParams) Do(ctx context.Context) (nodeID cdp.NodeID, err error) {
	// execute
	var res PushNodeByPathToFrontendReturns
	err = cdp.Execute(ctx, CommandPushNodeByPathToFrontend, p, &res)
	if err != nil {
		return 0, err
	}

	return res.NodeID, nil
}

// PushNodesByBackendIDsToFrontendParams requests that a batch of nodes is
// sent to the caller given their backend node ids.
type PushNodesByBackendIDsToFrontendParams struct {
	BackendNodeIDs []cdp.BackendNodeID `json:"backendNodeIds"` // The array of backend node ids.
}

// PushNodesByBackendIDsToFrontend requests that a batch of nodes is sent to
// the caller given their backend node ids.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-pushNodesByBackendIdsToFrontend
//
// parameters:
//
//	backendNodeIDs - The array of backend node ids.
func PushNodesByBackendIDsToFrontend(backendNodeIDs []cdp.BackendNodeID) *PushNodesByBackendIDsToFrontendParams {
	return &PushNodesByBackendIDsToFrontendParams{
		BackendNodeIDs: backendNodeIDs,
	}
}

// PushNodesByBackendIDsToFrontendReturns return values.
type PushNodesByBackendIDsToFrontendReturns struct {
	NodeIDs []cdp.NodeID `json:"nodeIds,omitempty"` // The array of ids of pushed nodes that correspond to the backend ids specified in backendNodeIds.
}

// Do executes DOM.pushNodesByBackendIdsToFrontend against the provided context.
//
// returns:
//
//	nodeIDs - The array of ids of pushed nodes that correspond to the backend ids specified in backendNodeIds.
func (p *PushNodesByBackendIDsToFrontendParams) Do(ctx context.Context) (nodeIDs []cdp.NodeID, err error) {
	// execute
	var res PushNodesByBackendIDsToFrontendReturns
	err = cdp.Execute(ctx, CommandPushNodesByBackendIDsToFrontend, p, &res)
	if err != nil {
		return nil, err
	}

	return res.NodeIDs, nil
}

// QuerySelectorParams executes querySelector on a given node.
type QuerySelectorParams struct {
	NodeID   cdp.NodeID `json:"nodeId"`   // Id of the node to query upon.
	Selector string     `json:"selector"` // Selector string.
}

// QuerySelector executes querySelector on a given node.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-querySelector
//
// parameters:
//
//	nodeID - Id of the node to query upon.
//	selector - Selector string.
func QuerySelector(nodeID cdp.NodeID, selector string) *QuerySelectorParams {
	return &QuerySelectorParams{
		NodeID:   nodeID,
		Selector: selector,
	}
}

// QuerySelectorReturns return values.
type QuerySelectorReturns struct {
	NodeID cdp.NodeID `json:"nodeId,omitempty"` // Query selector result.
}

// Do executes DOM.querySelector against the provided context.
//
// returns:
//
//	nodeID - Query selector result.
func (p *QuerySelectorParams) Do(ctx context.Context) (nodeID cdp.NodeID, err error) {
	// execute
	var res QuerySelectorReturns
	err = cdp.Execute(ctx, CommandQuerySelector, p, &res)
	if err != nil {
		return 0, err
	}

	return res.NodeID, nil
}

// QuerySelectorAllParams executes querySelectorAll on a given node.
type QuerySelectorAllParams struct {
	NodeID   cdp.NodeID `json:"nodeId"`   // Id of the node to query upon.
	Selector string     `json:"selector"` // Selector string.
}

// QuerySelectorAll executes querySelectorAll on a given node.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-querySelectorAll
//
// parameters:
//
//	nodeID - Id of the node to query upon.
//	selector - Selector string.
func QuerySelectorAll(nodeID cdp.NodeID, selector string) *QuerySelectorAllParams {
	return &QuerySelectorAllParams{
		NodeID:   nodeID,
		Selector: selector,
	}
}

// QuerySelectorAllReturns return values.
type QuerySelectorAllReturns struct {
	NodeIDs []cdp.NodeID `json:"nodeIds,omitempty"` // Query selector result.
}

// Do executes DOM.querySelectorAll against the provided context.
//
// returns:
//
//	nodeIDs - Query selector result.
func (p *QuerySelectorAllParams) Do(ctx context.Context) (nodeIDs []cdp.NodeID, err error) {
	// execute
	var res QuerySelectorAllReturns
	err = cdp.Execute(ctx, CommandQuerySelectorAll, p, &res)
	if err != nil {
		return nil, err
	}

	return res.NodeIDs, nil
}

// GetTopLayerElementsParams returns NodeIds of current top layer elements.
// Top layer is rendered closest to the user within a viewport, therefore its
// elements always appear on top of all other content.
type GetTopLayerElementsParams struct{}

// GetTopLayerElements returns NodeIds of current top layer elements. Top
// layer is rendered closest to the user within a viewport, therefore its
// elements always appear on top of all other content.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getTopLayerElements
func GetTopLayerElements() *GetTopLayerElementsParams {
	return &GetTopLayerElementsParams{}
}

// GetTopLayerElementsReturns return values.
type GetTopLayerElementsReturns struct {
	NodeIDs []cdp.NodeID `json:"nodeIds,omitempty"` // NodeIds of top layer elements
}

// Do executes DOM.getTopLayerElements against the provided context.
//
// returns:
//
//	nodeIDs - NodeIds of top layer elements
func (p *GetTopLayerElementsParams) Do(ctx context.Context) (nodeIDs []cdp.NodeID, err error) {
	// execute
	var res GetTopLayerElementsReturns
	err = cdp.Execute(ctx, CommandGetTopLayerElements, nil, &res)
	if err != nil {
		return nil, err
	}

	return res.NodeIDs, nil
}

// RedoParams re-does the last undone action.
type RedoParams struct{}

// Redo re-does the last undone action.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-redo
func Redo() *RedoParams {
	return &RedoParams{}
}

// Do executes DOM.redo against the provided context.
func (p *RedoParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandRedo, nil, nil)
}

// RemoveAttributeParams removes attribute with given name from an element
// with given id.
type RemoveAttributeParams struct {
	NodeID cdp.NodeID `json:"nodeId"` // Id of the element to remove attribute from.
	Name   string     `json:"name"`   // Name of the attribute to remove.
}

// RemoveAttribute removes attribute with given name from an element with
// given id.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-removeAttribute
//
// parameters:
//
//	nodeID - Id of the element to remove attribute from.
//	name - Name of the attribute to remove.
func RemoveAttribute(nodeID cdp.NodeID, name string) *RemoveAttributeParams {
	return &RemoveAttributeParams{
		NodeID: nodeID,
		Name:   name,
	}
}

// Do executes DOM.removeAttribute against the provided context.
func (p *RemoveAttributeParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandRemoveAttribute, p, nil)
}

// RemoveNodeParams removes node with given id.
type RemoveNodeParams struct {
	NodeID cdp.NodeID `json:"nodeId"` // Id of the node to remove.
}

// RemoveNode removes node with given id.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-removeNode
//
// parameters:
//
//	nodeID - Id of the node to remove.
func RemoveNode(nodeID cdp.NodeID) *RemoveNodeParams {
	return &RemoveNodeParams{
		NodeID: nodeID,
	}
}

// Do executes DOM.removeNode against the provided context.
func (p *RemoveNodeParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandRemoveNode, p, nil)
}

// RequestChildNodesParams requests that children of the node with given id
// are returned to the caller in form of setChildNodes events where not only
// immediate children are retrieved, but all children down to the specified
// depth.
type RequestChildNodesParams struct {
	NodeID cdp.NodeID `json:"nodeId"`           // Id of the node to get children for.
	Depth  int64      `json:"depth,omitempty"`  // The maximum depth at which children should be retrieved, defaults to 1. Use -1 for the entire subtree or provide an integer larger than 0.
	Pierce bool       `json:"pierce,omitempty"` // Whether or not iframes and shadow roots should be traversed when returning the sub-tree (default is false).
}

// RequestChildNodes requests that children of the node with given id are
// returned to the caller in form of setChildNodes events where not only
// immediate children are retrieved, but all children down to the specified
// depth.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-requestChildNodes
//
// parameters:
//
//	nodeID - Id of the node to get children for.
func RequestChildNodes(nodeID cdp.NodeID) *RequestChildNodesParams {
	return &RequestChildNodesParams{
		NodeID: nodeID,
	}
}

// WithDepth the maximum depth at which children should be retrieved,
// defaults to 1. Use -1 for the entire subtree or provide an integer larger
// than 0.
func (p RequestChildNodesParams) WithDepth(depth int64) *RequestChildNodesParams {
	p.Depth = depth
	return &p
}

// WithPierce whether or not iframes and shadow roots should be traversed
// when returning the sub-tree (default is false).
func (p RequestChildNodesParams) WithPierce(pierce bool) *RequestChildNodesParams {
	p.Pierce = pierce
	return &p
}

// Do executes DOM.requestChildNodes against the provided context.
func (p *RequestChildNodesParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandRequestChildNodes, p, nil)
}

// RequestNodeParams requests that the node is sent to the caller given the
// JavaScript node object reference. All nodes that form the path from the node
// to the root are also sent to the client as a series of setChildNodes
// notifications.
type RequestNodeParams struct {
	ObjectID runtime.RemoteObjectID `json:"objectId"` // JavaScript object id to convert into node.
}

// RequestNode requests that the node is sent to the caller given the
// JavaScript node object reference. All nodes that form the path from the node
// to the root are also sent to the client as a series of setChildNodes
// notifications.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-requestNode
//
// parameters:
//
//	objectID - JavaScript object id to convert into node.
func RequestNode(objectID runtime.RemoteObjectID) *RequestNodeParams {
	return &RequestNodeParams{
		ObjectID: objectID,
	}
}

// RequestNodeReturns return values.
type RequestNodeReturns struct {
	NodeID cdp.NodeID `json:"nodeId,omitempty"` // Node id for given object.
}

// Do executes DOM.requestNode against the provided context.
//
// returns:
//
//	nodeID - Node id for given object.
func (p *RequestNodeParams) Do(ctx context.Context) (nodeID cdp.NodeID, err error) {
	// execute
	var res RequestNodeReturns
	err = cdp.Execute(ctx, CommandRequestNode, p, &res)
	if err != nil {
		return 0, err
	}

	return res.NodeID, nil
}

// ResolveNodeParams resolves the JavaScript node object for a given NodeId
// or BackendNodeId.
type ResolveNodeParams struct {
	NodeID             cdp.NodeID                 `json:"nodeId,omitempty"`             // Id of the node to resolve.
	BackendNodeID      cdp.BackendNodeID          `json:"backendNodeId,omitempty"`      // Backend identifier of the node to resolve.
	ObjectGroup        string                     `json:"objectGroup,omitempty"`        // Symbolic group name that can be used to release multiple objects.
	ExecutionContextID runtime.ExecutionContextID `json:"executionContextId,omitempty"` // Execution context in which to resolve the node.
}

// ResolveNode resolves the JavaScript node object for a given NodeId or
// BackendNodeId.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-resolveNode
//
// parameters:
func ResolveNode() *ResolveNodeParams {
	return &ResolveNodeParams{}
}

// WithNodeID ID of the node to resolve.
func (p ResolveNodeParams) WithNodeID(nodeID cdp.NodeID) *ResolveNodeParams {
	p.NodeID = nodeID
	return &p
}

// WithBackendNodeID backend identifier of the node to resolve.
func (p ResolveNodeParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *ResolveNodeParams {
	p.BackendNodeID = backendNodeID
	return &p
}

// WithObjectGroup symbolic group name that can be used to release multiple
// objects.
func (p ResolveNodeParams) WithObjectGroup(objectGroup string) *ResolveNodeParams {
	p.ObjectGroup = objectGroup
	return &p
}

// WithExecutionContextID execution context in which to resolve the node.
func (p ResolveNodeParams) WithExecutionContextID(executionContextID runtime.ExecutionContextID) *ResolveNodeParams {
	p.ExecutionContextID = executionContextID
	return &p
}

// ResolveNodeReturns return values.
type ResolveNodeReturns struct {
	Object *runtime.RemoteObject `json:"object,omitempty"` // JavaScript object wrapper for given node.
}

// Do executes DOM.resolveNode against the provided context.
//
// returns:
//
//	object - JavaScript object wrapper for given node.
func (p *ResolveNodeParams) Do(ctx context.Context) (object *runtime.RemoteObject, err error) {
	// execute
	var res ResolveNodeReturns
	err = cdp.Execute(ctx, CommandResolveNode, p, &res)
	if err != nil {
		return nil, err
	}

	return res.Object, nil
}

// SetAttributeValueParams sets attribute for an element with given id.
type SetAttributeValueParams struct {
	NodeID cdp.NodeID `json:"nodeId"` // Id of the element to set attribute for.
	Name   string     `json:"name"`   // Attribute name.
	Value  string     `json:"value"`  // Attribute value.
}

// SetAttributeValue sets attribute for an element with given id.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-setAttributeValue
//
// parameters:
//
//	nodeID - Id of the element to set attribute for.
//	name - Attribute name.
//	value - Attribute value.
func SetAttributeValue(nodeID cdp.NodeID, name string, value string) *SetAttributeValueParams {
	return &SetAttributeValueParams{
		NodeID: nodeID,
		Name:   name,
		Value:  value,
	}
}

// Do executes DOM.setAttributeValue against the provided context.
func (p *SetAttributeValueParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandSetAttributeValue, p, nil)
}

// SetAttributesAsTextParams sets attributes on element with given id. This
// method is useful when user edits some existing attribute value and types in
// several attribute name/value pairs.
type SetAttributesAsTextParams struct {
	NodeID cdp.NodeID `json:"nodeId"`         // Id of the element to set attributes for.
	Text   string     `json:"text"`           // Text with a number of attributes. Will parse this text using HTML parser.
	Name   string     `json:"name,omitempty"` // Attribute name to replace with new attributes derived from text in case text parsed successfully.
}

// SetAttributesAsText sets attributes on element with given id. This method
// is useful when user edits some existing attribute value and types in several
// attribute name/value pairs.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-setAttributesAsText
//
// parameters:
//
//	nodeID - Id of the element to set attributes for.
//	text - Text with a number of attributes. Will parse this text using HTML parser.
func SetAttributesAsText(nodeID cdp.NodeID, text string) *SetAttributesAsTextParams {
	return &SetAttributesAsTextParams{
		NodeID: nodeID,
		Text:   text,
	}
}

// WithName attribute name to replace with new attributes derived from text
// in case text parsed successfully.
func (p SetAttributesAsTextParams) WithName(name string) *SetAttributesAsTextParams {
	p.Name = name
	return &p
}

// Do executes DOM.setAttributesAsText against the provided context.
func (p *SetAttributesAsTextParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandSetAttributesAsText, p, nil)
}

// SetFileInputFilesParams sets files for the given file input element.
type SetFileInputFilesParams struct {
	Files         []string               `json:"files"`                   // Array of file paths to set.
	NodeID        cdp.NodeID             `json:"nodeId,omitempty"`        // Identifier of the node.
	BackendNodeID cdp.BackendNodeID      `json:"backendNodeId,omitempty"` // Identifier of the backend node.
	ObjectID      runtime.RemoteObjectID `json:"objectId,omitempty"`      // JavaScript object id of the node wrapper.
}

// SetFileInputFiles sets files for the given file input element.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-setFileInputFiles
//
// parameters:
//
//	files - Array of file paths to set.
func SetFileInputFiles(files []string) *SetFileInputFilesParams {
	return &SetFileInputFilesParams{
		Files: files,
	}
}

// WithNodeID identifier of the node.
func (p SetFileInputFilesParams) WithNodeID(nodeID cdp.NodeID) *SetFileInputFilesParams {
	p.NodeID = nodeID
	return &p
}

// WithBackendNodeID identifier of the backend node.
func (p SetFileInputFilesParams) WithBackendNodeID(backendNodeID cdp.BackendNodeID) *SetFileInputFilesParams {
	p.BackendNodeID = backendNodeID
	return &p
}

// WithObjectID JavaScript object id of the node wrapper.
func (p SetFileInputFilesParams) WithObjectID(objectID runtime.RemoteObjectID) *SetFileInputFilesParams {
	p.ObjectID = objectID
	return &p
}

// Do executes DOM.setFileInputFiles against the provided context.
func (p *SetFileInputFilesParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandSetFileInputFiles, p, nil)
}

// SetNodeStackTracesEnabledParams sets if stack traces should be captured
// for Nodes. See Node.getNodeStackTraces. Default is disabled.
type SetNodeStackTracesEnabledParams struct {
	Enable bool `json:"enable"` // Enable or disable.
}

// SetNodeStackTracesEnabled sets if stack traces should be captured for
// Nodes. See Node.getNodeStackTraces. Default is disabled.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-setNodeStackTracesEnabled
//
// parameters:
//
//	enable - Enable or disable.
func SetNodeStackTracesEnabled(enable bool) *SetNodeStackTracesEnabledParams {
	return &SetNodeStackTracesEnabledParams{
		Enable: enable,
	}
}

// Do executes DOM.setNodeStackTracesEnabled against the provided context.
func (p *SetNodeStackTracesEnabledParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandSetNodeStackTracesEnabled, p, nil)
}

// GetNodeStackTracesParams gets stack traces associated with a Node. As of
// now, only provides stack trace for Node creation.
type GetNodeStackTracesParams struct {
	NodeID cdp.NodeID `json:"nodeId"` // Id of the node to get stack traces for.
}

// GetNodeStackTraces gets stack traces associated with a Node. As of now,
// only provides stack trace for Node creation.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getNodeStackTraces
//
// parameters:
//
//	nodeID - Id of the node to get stack traces for.
func GetNodeStackTraces(nodeID cdp.NodeID) *GetNodeStackTracesParams {
	return &GetNodeStackTracesParams{
		NodeID: nodeID,
	}
}

// GetNodeStackTracesReturns return values.
type GetNodeStackTracesReturns struct {
	Creation *runtime.StackTrace `json:"creation,omitempty"` // Creation stack trace, if available.
}

// Do executes DOM.getNodeStackTraces against the provided context.
//
// returns:
//
//	creation - Creation stack trace, if available.
func (p *GetNodeStackTracesParams) Do(ctx context.Context) (creation *runtime.StackTrace, err error) {
	// execute
	var res GetNodeStackTracesReturns
	err = cdp.Execute(ctx, CommandGetNodeStackTraces, p, &res)
	if err != nil {
		return nil, err
	}

	return res.Creation, nil
}

// GetFileInfoParams returns file information for the given File wrapper.
type GetFileInfoParams struct {
	ObjectID runtime.RemoteObjectID `json:"objectId"` // JavaScript object id of the node wrapper.
}

// GetFileInfo returns file information for the given File wrapper.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getFileInfo
//
// parameters:
//
//	objectID - JavaScript object id of the node wrapper.
func GetFileInfo(objectID runtime.RemoteObjectID) *GetFileInfoParams {
	return &GetFileInfoParams{
		ObjectID: objectID,
	}
}

// GetFileInfoReturns return values.
type GetFileInfoReturns struct {
	Path string `json:"path,omitempty"`
}

// Do executes DOM.getFileInfo against the provided context.
//
// returns:
//
//	path
func (p *GetFileInfoParams) Do(ctx context.Context) (path string, err error) {
	// execute
	var res GetFileInfoReturns
	err = cdp.Execute(ctx, CommandGetFileInfo, p, &res)
	if err != nil {
		return "", err
	}

	return res.Path, nil
}

// SetInspectedNodeParams enables console to refer to the node with given id
// via $x (see Command Line API for more details $x functions).
type SetInspectedNodeParams struct {
	NodeID cdp.NodeID `json:"nodeId"` // DOM node id to be accessible by means of $x command line API.
}

// SetInspectedNode enables console to refer to the node with given id via $x
// (see Command Line API for more details $x functions).
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-setInspectedNode
//
// parameters:
//
//	nodeID - DOM node id to be accessible by means of $x command line API.
func SetInspectedNode(nodeID cdp.NodeID) *SetInspectedNodeParams {
	return &SetInspectedNodeParams{
		NodeID: nodeID,
	}
}

// Do executes DOM.setInspectedNode against the provided context.
func (p *SetInspectedNodeParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandSetInspectedNode, p, nil)
}

// SetNodeNameParams sets node name for a node with given id.
type SetNodeNameParams struct {
	NodeID cdp.NodeID `json:"nodeId"` // Id of the node to set name for.
	Name   string     `json:"name"`   // New node's name.
}

// SetNodeName sets node name for a node with given id.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-setNodeName
//
// parameters:
//
//	nodeID - Id of the node to set name for.
//	name - New node's name.
func SetNodeName(nodeID cdp.NodeID, name string) *SetNodeNameParams {
	return &SetNodeNameParams{
		NodeID: nodeID,
		Name:   name,
	}
}

// SetNodeNameReturns return values.
type SetNodeNameReturns struct {
	NodeID cdp.NodeID `json:"nodeId,omitempty"` // New node's id.
}

// Do executes DOM.setNodeName against the provided context.
//
// returns:
//
//	nodeID - New node's id.
func (p *SetNodeNameParams) Do(ctx context.Context) (nodeID cdp.NodeID, err error) {
	// execute
	var res SetNodeNameReturns
	err = cdp.Execute(ctx, CommandSetNodeName, p, &res)
	if err != nil {
		return 0, err
	}

	return res.NodeID, nil
}

// SetNodeValueParams sets node value for a node with given id.
type SetNodeValueParams struct {
	NodeID cdp.NodeID `json:"nodeId"` // Id of the node to set value for.
	Value  string     `json:"value"`  // New node's value.
}

// SetNodeValue sets node value for a node with given id.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-setNodeValue
//
// parameters:
//
//	nodeID - Id of the node to set value for.
//	value - New node's value.
func SetNodeValue(nodeID cdp.NodeID, value string) *SetNodeValueParams {
	return &SetNodeValueParams{
		NodeID: nodeID,
		Value:  value,
	}
}

// Do executes DOM.setNodeValue against the provided context.
func (p *SetNodeValueParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandSetNodeValue, p, nil)
}

// SetOuterHTMLParams sets node HTML markup, returns new node id.
type SetOuterHTMLParams struct {
	NodeID    cdp.NodeID `json:"nodeId"`    // Id of the node to set markup for.
	OuterHTML string     `json:"outerHTML"` // Outer HTML markup to set.
}

// SetOuterHTML sets node HTML markup, returns new node id.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-setOuterHTML
//
// parameters:
//
//	nodeID - Id of the node to set markup for.
//	outerHTML - Outer HTML markup to set.
func SetOuterHTML(nodeID cdp.NodeID, outerHTML string) *SetOuterHTMLParams {
	return &SetOuterHTMLParams{
		NodeID:    nodeID,
		OuterHTML: outerHTML,
	}
}

// Do executes DOM.setOuterHTML against the provided context.
func (p *SetOuterHTMLParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandSetOuterHTML, p, nil)
}

// UndoParams undoes the last performed action.
type UndoParams struct{}

// Undo undoes the last performed action.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-undo
func Undo() *UndoParams {
	return &UndoParams{}
}

// Do executes DOM.undo against the provided context.
func (p *UndoParams) Do(ctx context.Context) (err error) {
	return cdp.Execute(ctx, CommandUndo, nil, nil)
}

// GetFrameOwnerParams returns iframe node that owns iframe with the given
// domain.
type GetFrameOwnerParams struct {
	FrameID cdp.FrameID `json:"frameId"`
}

// GetFrameOwner returns iframe node that owns iframe with the given domain.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getFrameOwner
//
// parameters:
//
//	frameID
func GetFrameOwner(frameID cdp.FrameID) *GetFrameOwnerParams {
	return &GetFrameOwnerParams{
		FrameID: frameID,
	}
}

// GetFrameOwnerReturns return values.
type GetFrameOwnerReturns struct {
	BackendNodeID cdp.BackendNodeID `json:"backendNodeId,omitempty"` // Resulting node.
	NodeID        cdp.NodeID        `json:"nodeId,omitempty"`        // Id of the node at given coordinates, only when enabled and requested document.
}

// Do executes DOM.getFrameOwner against the provided context.
//
// returns:
//
//	backendNodeID - Resulting node.
//	nodeID - Id of the node at given coordinates, only when enabled and requested document.
func (p *GetFrameOwnerParams) Do(ctx context.Context) (backendNodeID cdp.BackendNodeID, nodeID cdp.NodeID, err error) {
	// execute
	var res GetFrameOwnerReturns
	err = cdp.Execute(ctx, CommandGetFrameOwner, p, &res)
	if err != nil {
		return 0, 0, err
	}

	return res.BackendNodeID, res.NodeID, nil
}

// GetContainerForNodeParams returns the query container of the given node
// based on container query conditions: containerName, physical, and logical
// axes. If no axes are provided, the style container is returned, which is the
// direct parent or the closest element with a matching container-name.
type GetContainerForNodeParams struct {
	NodeID        cdp.NodeID   `json:"nodeId"`
	ContainerName string       `json:"containerName,omitempty"`
	PhysicalAxes  PhysicalAxes `json:"physicalAxes,omitempty"`
	LogicalAxes   LogicalAxes  `json:"logicalAxes,omitempty"`
}

// GetContainerForNode returns the query container of the given node based on
// container query conditions: containerName, physical, and logical axes. If no
// axes are provided, the style container is returned, which is the direct
// parent or the closest element with a matching container-name.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getContainerForNode
//
// parameters:
//
//	nodeID
func GetContainerForNode(nodeID cdp.NodeID) *GetContainerForNodeParams {
	return &GetContainerForNodeParams{
		NodeID: nodeID,
	}
}

// WithContainerName [no description].
func (p GetContainerForNodeParams) WithContainerName(containerName string) *GetContainerForNodeParams {
	p.ContainerName = containerName
	return &p
}

// WithPhysicalAxes [no description].
func (p GetContainerForNodeParams) WithPhysicalAxes(physicalAxes PhysicalAxes) *GetContainerForNodeParams {
	p.PhysicalAxes = physicalAxes
	return &p
}

// WithLogicalAxes [no description].
func (p GetContainerForNodeParams) WithLogicalAxes(logicalAxes LogicalAxes) *GetContainerForNodeParams {
	p.LogicalAxes = logicalAxes
	return &p
}

// GetContainerForNodeReturns return values.
type GetContainerForNodeReturns struct {
	NodeID cdp.NodeID `json:"nodeId,omitempty"` // The container node for the given node, or null if not found.
}

// Do executes DOM.getContainerForNode against the provided context.
//
// returns:
//
//	nodeID - The container node for the given node, or null if not found.
func (p *GetContainerForNodeParams) Do(ctx context.Context) (nodeID cdp.NodeID, err error) {
	// execute
	var res GetContainerForNodeReturns
	err = cdp.Execute(ctx, CommandGetContainerForNode, p, &res)
	if err != nil {
		return 0, err
	}

	return res.NodeID, nil
}

// GetQueryingDescendantsForContainerParams returns the descendants of a
// container query container that have container queries against this container.
type GetQueryingDescendantsForContainerParams struct {
	NodeID cdp.NodeID `json:"nodeId"` // Id of the container node to find querying descendants from.
}

// GetQueryingDescendantsForContainer returns the descendants of a container
// query container that have container queries against this container.
//
// See: https://chromedevtools.github.io/devtools-protocol/tot/DOM#method-getQueryingDescendantsForContainer
//
// parameters:
//
//	nodeID - Id of the container node to find querying descendants from.
func GetQueryingDescendantsForContainer(nodeID cdp.NodeID) *GetQueryingDescendantsForContainerParams {
	return &GetQueryingDescendantsForContainerParams{
		NodeID: nodeID,
	}
}

// GetQueryingDescendantsForContainerReturns return values.
type GetQueryingDescendantsForContainerReturns struct {
	NodeIDs []cdp.NodeID `json:"nodeIds,omitempty"` // Descendant nodes with container queries against the given container.
}

// Do executes DOM.getQueryingDescendantsForContainer against the provided context.
//
// returns:
//
//	nodeIDs - Descendant nodes with container queries against the given container.
func (p *GetQueryingDescendantsForContainerParams) Do(ctx context.Context) (nodeIDs []cdp.NodeID, err error) {
	// execute
	var res GetQueryingDescendantsForContainerReturns
	err = cdp.Execute(ctx, CommandGetQueryingDescendantsForContainer, p, &res)
	if err != nil {
		return nil, err
	}

	return res.NodeIDs, nil
}

// Command names.
const (
	CommandCollectClassNamesFromSubtree       = "DOM.collectClassNamesFromSubtree"
	CommandCopyTo                             = "DOM.copyTo"
	CommandDescribeNode                       = "DOM.describeNode"
	CommandScrollIntoViewIfNeeded             = "DOM.scrollIntoViewIfNeeded"
	CommandDisable                            = "DOM.disable"
	CommandDiscardSearchResults               = "DOM.discardSearchResults"
	CommandEnable                             = "DOM.enable"
	CommandFocus                              = "DOM.focus"
	CommandGetAttributes                      = "DOM.getAttributes"
	CommandGetBoxModel                        = "DOM.getBoxModel"
	CommandGetContentQuads                    = "DOM.getContentQuads"
	CommandGetDocument                        = "DOM.getDocument"
	CommandGetNodesForSubtreeByStyle          = "DOM.getNodesForSubtreeByStyle"
	CommandGetNodeForLocation                 = "DOM.getNodeForLocation"
	CommandGetOuterHTML                       = "DOM.getOuterHTML"
	CommandGetRelayoutBoundary                = "DOM.getRelayoutBoundary"
	CommandGetSearchResults                   = "DOM.getSearchResults"
	CommandMarkUndoableState                  = "DOM.markUndoableState"
	CommandMoveTo                             = "DOM.moveTo"
	CommandPerformSearch                      = "DOM.performSearch"
	CommandPushNodeByPathToFrontend           = "DOM.pushNodeByPathToFrontend"
	CommandPushNodesByBackendIDsToFrontend    = "DOM.pushNodesByBackendIdsToFrontend"
	CommandQuerySelector                      = "DOM.querySelector"
	CommandQuerySelectorAll                   = "DOM.querySelectorAll"
	CommandGetTopLayerElements                = "DOM.getTopLayerElements"
	CommandRedo                               = "DOM.redo"
	CommandRemoveAttribute                    = "DOM.removeAttribute"
	CommandRemoveNode                         = "DOM.removeNode"
	CommandRequestChildNodes                  = "DOM.requestChildNodes"
	CommandRequestNode                        = "DOM.requestNode"
	CommandResolveNode                        = "DOM.resolveNode"
	CommandSetAttributeValue                  = "DOM.setAttributeValue"
	CommandSetAttributesAsText                = "DOM.setAttributesAsText"
	CommandSetFileInputFiles                  = "DOM.setFileInputFiles"
	CommandSetNodeStackTracesEnabled          = "DOM.setNodeStackTracesEnabled"
	CommandGetNodeStackTraces                 = "DOM.getNodeStackTraces"
	CommandGetFileInfo                        = "DOM.getFileInfo"
	CommandSetInspectedNode                   = "DOM.setInspectedNode"
	CommandSetNodeName                        = "DOM.setNodeName"
	CommandSetNodeValue                       = "DOM.setNodeValue"
	CommandSetOuterHTML                       = "DOM.setOuterHTML"
	CommandUndo                               = "DOM.undo"
	CommandGetFrameOwner                      = "DOM.getFrameOwner"
	CommandGetContainerForNode                = "DOM.getContainerForNode"
	CommandGetQueryingDescendantsForContainer = "DOM.getQueryingDescendantsForContainer"
)
