<commit_before>package marionette_client

import (
	"encoding/json"
	"fmt"
	"math"
	"strings"
)

const (
	MARIONETTE_PROTOCOL_V2 = 2
	MARIONETTE_PROTOCOL_V3 = 3

	WEBDRIVER_ELEMENT_KEY = "element-6066-11e4-a52e-4f735466cecf"
)

var RunningInDebugMode bool = false

type session struct {
	SessionId string
}

type Client struct {
	session
	transport Transporter
}

func NewClient() *Client {
	return &Client{
		session{},
		&MarionetteTransport{},
	}
}

func (c *Client) Transport(t Transporter) {
	c.transport = t
}

func (c *Client) SessionID() string {
	return c.SessionId
}

func (c *Client) Connect(host string, port int) error {
	return c.transport.Connect(host, port)
}

// Send the current session's capabilities to the client.
// Capabilities informs the client of which WebDriver features are
// supported by Firefox and Marionette.  They are immutable for the
// length of the session.
// The return value is an immutable map of string keys
// ("capabilities") to values, which may be of types boolean,
// numerical or string.
func (c *Client) Capabilities() (*Capabilities, error) {
	buf, err := c.transport.Send("getSessionCapabilities", nil)
	if err != nil {
		return nil, err
	}

	response := map[string]*Capabilities{"Capabilities": &Capabilities{}}
	err = json.Unmarshal([]byte(buf.Value), &response)
	if err != nil {
		return nil, err
	}

	cap, _ := response["capabilities"]
	return cap, nil
}

/////////////
// SESSION //
/////////////

// create new session
func (c *Client) NewSession(sessionId string, cap *Capabilities) (*Response, error) {
	data := map[string]interface{}{
		"sessionId":    sessionId,
		"capabilities": cap,
	}

	response, err := c.transport.Send("newSession", data)
	if err != nil {
		return nil, err
	}

	err = json.Unmarshal([]byte(response.Value), &c)
	if err != nil {
		return nil, err
	}

	return response, nil
}

// Marionette currently only accepts a session id, so if
// we call delete session can also close the TCP Connection
func (c *Client) DeleteSession() error {
	_, err := c.transport.Send("deleteSession", nil)
	if err != nil {
		return err
	}

	return c.transport.Close()
}

// Set the timeout for asynchronous script execution.
//
// param number ms
//     Time in milliseconds.
func (c *Client) SetScriptTimeout(milliseconds int) (*Response, error) {
	return timeouts(&c.transport, "script", milliseconds)
}

// Set timeout for searching for elements.
//
// param number ms
//     Search timeout in milliseconds.
func (c *Client) SetSearchTimeout(milliseconds int) (*Response, error) {
	return timeouts(&c.transport, "implicit", milliseconds)
}

// Set timeout for page loading.
//
// param number ms
//     Search timeout in milliseconds.
func (c *Client) SetPageTimeout(milliseconds int) (*Response, error) {
	return timeouts(&c.transport, "pageLoad", milliseconds)
}

// Set timeout for page loading, searching, and scripts.
//
// param string type
//     Type of timeout.
// param number ms
//     Timeout in milliseconds.
func timeouts(transport *Transporter, typ string, milliseconds int) (*Response, error) {
	r, err := (*transport).Send("timeouts", map[string]interface{}{"type": typ, "ms": milliseconds})
	if err != nil {
		return nil, err
	}

	return r, nil
}

////////////////
// NAVIGATION //
////////////////

// deprecated use Navigate()
func (c *Client) Get(url string) (*Response, error) {
	return c.Navigate(url)
}

// open url
func (c *Client) Navigate(url string) (*Response, error) {
	r, err := c.transport.Send("get", map[string]string{"url": url})
	if err != nil {
		return nil, err
	}

	return r, nil
}

// get title
func (c *Client) Title() (string, error) {
	r, err := c.transport.Send("getTitle", map[string]string{})
	if err != nil {
		return "", err
	}

	var d = map[string]string{}
	err = json.Unmarshal([]byte(r.Value), &d)
	if err != nil {
		return "", err
	}

	return d["value"], nil
}

// deprecated, use Url() instead
func (c *Client) CurrentUrl() (string, error) {
	return c.Url()
}

// get current url
func (c *Client) Url() (string, error) {
	r, err := c.transport.Send("getCurrentUrl", nil)
	if err != nil {
		return "", err
	}

	var url map[string]string
	err = json.Unmarshal([]byte(r.Value), &url)
	if err != nil {
		return "", err
	}

	return url["value"], nil
}

// refresh
func (c *Client) Refresh() error {
	_, err := c.transport.Send("refresh", nil)
	if err != nil {
		return err
	}

	return nil
}

// back
func (c *Client) Back() error {
	_, err := c.transport.Send("goBack", nil)
	if err != nil {
		return err
	}

	return nil
}

// forward
func (c *Client) Forward() error {
	_, err := c.transport.Send("goForward", nil)
	if err != nil {
		return err
	}

	return nil
}

// Log message.  Accepts user defined log-level.
//
// param string value
//     Log message.
// param string level
//     Arbitrary log level.
func (c *Client) Log(message string, level string) (*Response, error) {
	response, err := c.transport.Send("log", map[string]string{"value": message, "level": level})
	if err != nil {
		return nil, err
	}

	return response, nil
}

//  Return all logged messages.
func (c *Client) Logs() (*Response, error) {
	response, err := c.transport.Send("getLogs", nil)
	if err != nil {
		return nil, err
	}

	return response, nil
}

// Sets the context of the subsequent commands to be either "chrome" or
// "content".
//
// param string value
//     Name of the context to be switched to.  Must be one of "chrome" or
//     "content".
func (c *Client) SetContext(value Context) (*Response, error) {
	response, err := c.transport.Send("setContext", map[string]string{"value": fmt.Sprint(value)})
	if err != nil {
		return nil, err
	}

	return response, nil
}

//  Gets the context of the server, either "chrome" or "content".
func (c *Client) Context() (*Response, error) {
	response, err := c.transport.Send("getContext", nil)
	if err != nil {
		return nil, err
	}

	return response, nil
}

/////////////////////
// WINDOWS HANDLES //
/////////////////////

func (c *Client) CurrentWindowHandle() (string, error) {
	r, err := c.transport.Send("getWindowHandle", nil)
	if err != nil {
		return "", err
	}

	var d map[string]string
	err = json.Unmarshal([]byte(r.Value), &d)
	if err != nil {
		return "", err
	}
	return d["value"], nil
}

//"getChromeWindowHandle": GeckoDriver.prototype.getChromeWindowHandle,
//"getCurrentChromeWindowHandle": GeckoDriver.prototype.getChromeWindowHandle,
func (c *Client) CurrentChromeWindowHandle() (*Response, error) {
	r, err := c.transport.Send("getCurrentChromeWindowHandle", nil)
	if err != nil {
		return nil, err
	}

	return r, nil
}

func (c *Client) WindowHandles() ([]string, error) {
	r, err := c.transport.Send("getWindowHandles", nil)
	if err != nil {
		return nil, err
	}

	var d []string
	err = json.Unmarshal([]byte(r.Value), &d)
	if err != nil {
		return nil, err
	}

	return d, nil
}

func (c *Client) SwitchToWindow(name string) error {
	_, err := c.transport.Send("switchToWindow", map[string]interface{}{"name": name})
	if err != nil {
		return err
	}

	return nil
}

func (c *Client) WindowSize() (rv *Size, err error) {
	r, err := c.transport.Send("getWindowSize", nil)
	if err != nil {
		return nil, err
	}

	rv = new(Size)
	err = json.Unmarshal([]byte(r.Value), &rv)
	if err != nil {
		return nil, err
	}

	return
}

func (c *Client) SetWindowSize(s *Size) (rv *Size, err error) {
	r, err := c.transport.Send("setWindowSize", map[string]interface{}{"width": math.Floor(s.Width), "height": math.Floor(s.Height)})
	if err != nil {
		return nil, err
	}

	rv = new(Size)
	err = json.Unmarshal([]byte(r.Value), &rv)
	if err != nil {
		return nil, err
	}

	return
}

func (c *Client) MaximizeWindow() error {
	_, err := c.transport.Send("maximizeWindow", nil)
	if err != nil {
		return err
	}

	return nil
}

func (c *Client) CloseWindow() (*Response, error) {
	r, err := c.transport.Send("close", nil)
	if err != nil {
		return nil, err
	}

	return r, nil
}

////////////
// FRAMES //<commit_msg>added some doc blocks for exported methods #17<commit_after>package marionette_client

import (
	"encoding/json"
	"fmt"
	"math"
	"strings"
)

const (
	MARIONETTE_PROTOCOL_V2 = 2
	MARIONETTE_PROTOCOL_V3 = 3

	WEBDRIVER_ELEMENT_KEY = "element-6066-11e4-a52e-4f735466cecf"
)

var RunningInDebugMode bool = false

type session struct {
	SessionId string
}

type Client struct {
	session
	transport Transporter
}

func NewClient() *Client {
	return &Client{
		session{},
		&MarionetteTransport{},
	}
}

func (c *Client) Transport(t Transporter) {
	c.transport = t
}

func (c *Client) SessionID() string {
	return c.SessionId
}

func (c *Client) Connect(host string, port int) error {
	return c.transport.Connect(host, port)
}

// Capabilities Send the current session's capabilities to the client.
// Capabilities informs the client of which WebDriver features are
// supported by Firefox and Marionette.  They are immutable for the
// length of the session.
// The return value is an immutable map of string keys
// ("capabilities") to values, which may be of types boolean,
// numerical or string.
func (c *Client) Capabilities() (*Capabilities, error) {
	buf, err := c.transport.Send("getSessionCapabilities", nil)
	if err != nil {
		return nil, err
	}

	response := map[string]*Capabilities{"Capabilities": &Capabilities{}}
	err = json.Unmarshal([]byte(buf.Value), &response)
	if err != nil {
		return nil, err
	}

	cap, _ := response["capabilities"]
	return cap, nil
}

/////////////
// SESSION //
/////////////

// NewSession create new session
func (c *Client) NewSession(sessionId string, cap *Capabilities) (*Response, error) {
	data := map[string]interface{}{
		"sessionId":    sessionId,
		"capabilities": cap,
	}

	response, err := c.transport.Send("newSession", data)
	if err != nil {
		return nil, err
	}

	err = json.Unmarshal([]byte(response.Value), &c)
	if err != nil {
		return nil, err
	}

	return response, nil
}

// DeleteSession Marionette currently only accepts a session id, so if
// we call delete session can also close the TCP Connection
func (c *Client) DeleteSession() error {
	_, err := c.transport.Send("deleteSession", nil)
	if err != nil {
		return err
	}

	return c.transport.Close()
}

// SetScriptTimeout Set the timeout for asynchronous script execution.
func (c *Client) SetScriptTimeout(milliseconds int) (*Response, error) {
	return timeouts(&c.transport, "script", milliseconds)
}

// SetSearchTimeout Set timeout for searching for elements.
func (c *Client) SetSearchTimeout(milliseconds int) (*Response, error) {
	return timeouts(&c.transport, "implicit", milliseconds)
}

// SetPageTimeout Set timeout for page loading.
func (c *Client) SetPageTimeout(milliseconds int) (*Response, error) {
	return timeouts(&c.transport, "pageLoad", milliseconds)
}

// Set timeout for page loading, searching, and scripts.
//
// param string type
//     Type of timeout.
// param number ms
//     Timeout in milliseconds.
func timeouts(transport *Transporter, typ string, milliseconds int) (*Response, error) {
	r, err := (*transport).Send("timeouts", map[string]interface{}{"type": typ, "ms": milliseconds})
	if err != nil {
		return nil, err
	}

	return r, nil
}

////////////////
// NAVIGATION //
////////////////

// Get deprecated use Navigate()
func (c *Client) Get(url string) (*Response, error) {
	return c.Navigate(url)
}

// Navigate open url
func (c *Client) Navigate(url string) (*Response, error) {
	r, err := c.transport.Send("get", map[string]string{"url": url})
	if err != nil {
		return nil, err
	}

	return r, nil
}

// Title get title
func (c *Client) Title() (string, error) {
	r, err := c.transport.Send("getTitle", map[string]string{})
	if err != nil {
		return "", err
	}

	var d = map[string]string{}
	err = json.Unmarshal([]byte(r.Value), &d)
	if err != nil {
		return "", err
	}

	return d["value"], nil
}

// CurrentUrl deprecated, use Url() instead
func (c *Client) CurrentUrl() (string, error) {
	return c.Url()
}

// Url get current url
func (c *Client) Url() (string, error) {
	r, err := c.transport.Send("getCurrentUrl", nil)
	if err != nil {
		return "", err
	}

	var url map[string]string
	err = json.Unmarshal([]byte(r.Value), &url)
	if err != nil {
		return "", err
	}

	return url["value"], nil
}

// Refresh refresh
func (c *Client) Refresh() error {
	_, err := c.transport.Send("refresh", nil)
	if err != nil {
		return err
	}

	return nil
}

// Back go back in navigation history
func (c *Client) Back() error {
	_, err := c.transport.Send("goBack", nil)
	if err != nil {
		return err
	}

	return nil
}

// Forward go forward in navigation history
func (c *Client) Forward() error {
	_, err := c.transport.Send("goForward", nil)
	if err != nil {
		return err
	}

	return nil
}

// Log Accepts user defined log-level.
func (c *Client) Log(message string, level string) (*Response, error) {
	response, err := c.transport.Send("log", map[string]string{"value": message, "level": level})
	if err != nil {
		return nil, err
	}

	return response, nil
}

// Logs Return all logged messages.
func (c *Client) Logs() (*Response, error) {
	response, err := c.transport.Send("getLogs", nil)
	if err != nil {
		return nil, err
	}

	return response, nil
}

// SetContext Sets the context of the subsequent commands to be either "chrome" or "content".
// Must be one of "chrome" or "content" only.
func (c *Client) SetContext(value Context) (*Response, error) {
	response, err := c.transport.Send("setContext", map[string]string{"value": fmt.Sprint(value)})
	if err != nil {
		return nil, err
	}

	return response, nil
}

// Context Gets the context of the server, either "chrome" or "content".
func (c *Client) Context() (*Response, error) {
	response, err := c.transport.Send("getContext", nil)
	if err != nil {
		return nil, err
	}

	return response, nil
}

/////////////////////
// WINDOWS HANDLES //
/////////////////////

// CurrentWindowHandle returns the current window ID
func (c *Client) CurrentWindowHandle() (string, error) {
	r, err := c.transport.Send("getWindowHandle", nil)
	if err != nil {
		return "", err
	}

	var d map[string]string
	err = json.Unmarshal([]byte(r.Value), &d)
	if err != nil {
		return "", err
	}
	return d["value"], nil
}


// CurrentChromeWindowHandle returns the current chrome window ID
//"getChromeWindowHandle": GeckoDriver.prototype.getChromeWindowHandle,
//"getCurrentChromeWindowHandle": GeckoDriver.prototype.getChromeWindowHandle,
func (c *Client) CurrentChromeWindowHandle() (*Response, error) {
	r, err := c.transport.Send("getCurrentChromeWindowHandle", nil)
	if err != nil {
		return nil, err
	}

	return r, nil
}

// WindowHandles return array of window ID currently opened
func (c *Client) WindowHandles() ([]string, error) {
	r, err := c.transport.Send("getWindowHandles", nil)
	if err != nil {
		return nil, err
	}

	var d []string
	err = json.Unmarshal([]byte(r.Value), &d)
	if err != nil {
		return nil, err
	}

	return d, nil
}

// SwitchToWindow switch to specific window.
func (c *Client) SwitchToWindow(name string) error {
	_, err := c.transport.Send("switchToWindow", map[string]interface{}{"name": name})
	if err != nil {
		return err
	}

	return nil
}

// WindowSize returns the window size
func (c *Client) WindowSize() (rv *Size, err error) {
	r, err := c.transport.Send("getWindowSize", nil)
	if err != nil {
		return nil, err
	}

	rv = new(Size)
	err = json.Unmarshal([]byte(r.Value), &rv)
	if err != nil {
		return nil, err
	}

	return
}

// SetWindowSize sets window size
func (c *Client) SetWindowSize(s *Size) (rv *Size, err error) {
	r, err := c.transport.Send("setWindowSize", map[string]interface{}{"width": math.Floor(s.Width), "height": math.Floor(s.Height)})
	if err != nil {
		return nil, err
	}

	rv = new(Size)
	err = json.Unmarshal([]byte(r.Value), &rv)
	if err != nil {
		return nil, err
	}

	return
}

// MaximizeWindow maximizes window.
func (c *Client) MaximizeWindow() error {
	_, err := c.transport.Send("maximizeWindow", nil)
	if err != nil {
		return err
	}

	return nil
}

// CloseWindow closes current window.
func (c *Client) CloseWindow() (*Response, error) {
	r, err := c.transport.Send("close", nil)
	if err != nil {
		return nil, err
	}

	return r, nil
}

////////////
// FRAMES //
{'fraction_non_alphanumeric': 0.1589056324110672, 'fraction_numerical': 0.0025938735177865615, 'mean_word_length': 3.569130925507901, 'pattern_counts': {'":': 28, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7162381', 'n_tokens_mistral': 5544, 'n_tokens_neox': 5326, 'n_words': 1720}