# Copyright 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import os

from telemetry.core import exceptions
from telemetry.core import util

DEFAULT_WEB_CONTENTS_TIMEOUT = 90

# TODO(achuith, dtu, nduca): Add unit tests specifically for WebContents,
# independent of Tab.
class WebContents(object):
  """Represents web contents in the browser"""
  def __init__(self, inspector_backend):
    self._inspector_backend = inspector_backend

    with open(os.path.join(os.path.dirname(__file__),
        'network_quiescence.js')) as f:
      self._quiescence_js = f.read()

  @property
  def id(self):
    """Return the unique id string for this tab object."""
    return self._inspector_backend.id

  def GetUrl(self):
    """Returns the URL to which the WebContents is connected.

    Raises:
      exceptions.Error: If there is an error in inspector backend connection.
    """
    return self._inspector_backend.url

  def GetWebviewContexts(self):
    """Returns a list of webview contexts within the current inspector backend.

    Returns:
      A list of WebContents objects representing the webview contexts.

    Raises:
      exceptions.Error: If there is an error in inspector backend connection.
    """
    webviews = []
    inspector_backends = self._inspector_backend.GetWebviewInspectorBackends()
    for inspector_backend in inspector_backends:
      webviews.append(WebContents(inspector_backend))
    return webviews

  def WaitForDocumentReadyStateToBeComplete(self,
      timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
    """Waits for the document to finish loading.

    Raises:
      exceptions.Error: See WaitForJavaScriptExpression() for a detailed list
      of possible exceptions.
    """

    self.WaitForJavaScriptExpression(
        'document.readyState == "complete"', timeout)

  def WaitForDocumentReadyStateToBeInteractiveOrBetter(self,
      timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
    """Waits for the document to be interactive.

    Raises:
      exceptions.Error: See WaitForJavaScriptExpression() for a detailed list
      of possible exceptions.
    """
    self.WaitForJavaScriptExpression(
        'document.readyState == "interactive" || '
        'document.readyState == "complete"', timeout)

  def WaitForJavaScriptExpression(self, expr, timeout):
    """Waits for the given JavaScript expression to be True.

    This method is robust against any given Evaluation timing out.

    Args:
      expr: The expression to evaluate.
      timeout: The number of seconds to wait for the expression to be True.

    Raises:
      exceptions.TimeoutException: On a timeout.
      exceptions.Error: See EvaluateJavaScript() for a detailed list of
      possible exceptions.
    """
    def IsJavaScriptExpressionTrue():
      try:
        return bool(self.EvaluateJavaScript(expr))
      except exceptions.TimeoutException:
        # If the main thread is busy for longer than Evaluate's timeout, we
        # may time out here early. Instead, we want to wait for the full
        # timeout of this method.
        return False
    try:
      util.WaitFor(IsJavaScriptExpressionTrue, timeout)
    except exceptions.TimeoutException as e:
      # Try to make timeouts a little more actionable by dumping console output.
      debug_message = None
      try:
        debug_message = (
            'Console output:\n%s' %
            self._inspector_backend.GetCurrentConsoleOutputBuffer())
      except Exception as e:
        debug_message = (
            'Exception thrown when trying to capture console output: %s' %
            repr(e))
      raise exceptions.TimeoutException(
          e.message + '\n' + debug_message)

  def HasReachedQuiescence(self):
    """Determine whether the page has reached quiescence after loading.

    Returns:
      True if 2 seconds have passed since last resource received, false
      otherwise.
    Raises:
      exceptions.Error: See EvaluateJavaScript() for a detailed list of
      possible exceptions.
    """

    # Inclusion of the script that provides
    # window.__telemetry_testHasReachedNetworkQuiescence()
    # is idempotent, it's run on every call because WebContents doesn't track
    # page loads and we need to execute anew for every newly loaded page.
    has_reached_quiescence = (
        self.EvaluateJavaScript(self._quiescence_js +
            "window.__telemetry_testHasReachedNetworkQuiescence()"))
    return has_reached_quiescence

  def ExecuteJavaScript(self, statement, timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
    """Executes statement in JavaScript. Does not return the result.

    If the statement failed to evaluate, EvaluateException will be raised.

    Raises:
      exceptions.Error: See ExecuteJavaScriptInContext() for a detailed list of
      possible exceptions.
    """
    return self.ExecuteJavaScriptInContext(
        statement, context_id=None, timeout=timeout)

  def EvaluateJavaScript(self, expr, timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
    """Evalutes expr in JavaScript and returns the JSONized result.

    Consider using ExecuteJavaScript for cases where the result of the
    expression is not needed.

    If evaluation throws in JavaScript, a Python EvaluateException will
    be raised.

    If the result of the evaluation cannot be JSONized, then an
    EvaluationException will be raised.

    Raises:
      exceptions.Error: See EvaluateJavaScriptInContext() for a detailed list
      of possible exceptions.
    """
    return self.EvaluateJavaScriptInContext(
        expr, context_id=None, timeout=timeout)

  def ExecuteJavaScriptInContext(self, expr, context_id,
                                 timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
    """Similar to ExecuteJavaScript, except context_id can refer to an iframe.
    The main page has context_id=1, the first iframe context_id=2, etc.

    Raises:
      exceptions.EvaluateException
      exceptions.WebSocketDisconnected
      exceptions.TimeoutException
      exceptions.DevtoolsTargetCrashException
    """
    return self._inspector_backend.ExecuteJavaScript(
        expr, context_id=context_id, timeout=timeout)

  def EvaluateJavaScriptInContext(self, expr, context_id,
                                  timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
    """Similar to ExecuteJavaScript, except context_id can refer to an iframe.
    The main page has context_id=1, the first iframe context_id=2, etc.

    Raises:
      exceptions.EvaluateException
      exceptions.WebSocketDisconnected
      exceptions.TimeoutException
      exceptions.DevtoolsTargetCrashException
    """
    return self._inspector_backend.EvaluateJavaScript(
        expr, context_id=context_id, timeout=timeout)

  def EnableAllContexts(self):
    """Enable all contexts in a page. Returns the number of available contexts.

    Raises:
      exceptions.WebSocketDisconnected
      exceptions.TimeoutException
      exceptions.DevtoolsTargetCrashException
    """
    return self._inspector_backend.EnableAllContexts()

  def WaitForNavigate(self, timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
    """Waits for the navigation to complete.

    The current page is expect to be in a navigation.
    This function returns when the navigation is complete or when
    the timeout has been exceeded.

    Raises:
      exceptions.TimeoutException
      exceptions.DevtoolsTargetCrashException
    """
    self._inspector_backend.WaitForNavigate(timeout)

  def Navigate(self, url, script_to_evaluate_on_commit=None,
               timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
    """Navigates to url.

    If |script_to_evaluate_on_commit| is given, the script source string will be
    evaluated when the navigation is committed. This is after the context of
    the page exists, but before any script on the page itself has executed.

    Raises:
      exceptions.TimeoutException
      exceptions.DevtoolsTargetCrashException
    """
    self._inspector_backend.Navigate(url, script_to_evaluate_on_commit, timeout)

  def IsAlive(self):
    """Whether the WebContents is still operating normally.

    Since WebContents function asynchronously, this method does not guarantee
    that the WebContents will still be alive at any point in the future.

    Returns:
      A boolean indicating whether the WebContents is opearting normally.
    """
    return self._inspector_backend.IsInspectable()

  def CloseConnections(self):
    """Closes all TCP sockets held open by the browser.

    Raises:
      exceptions.DevtoolsTargetCrashException if the tab is not alive.
    """
    if not self.IsAlive():
      raise exceptions.DevtoolsTargetCrashException
    self.ExecuteJavaScript('window.chrome && chrome.benchmarking &&'
                           'chrome.benchmarking.closeConnections()')

  def SynthesizeScrollGesture(self, x=100, y=800, xDistance=0, yDistance=-500,
                              xOverscroll=None, yOverscroll=None,
                              preventFling=True, speed=None,
                              gestureSourceType=None, repeatCount=None,
                              repeatDelayMs=None, interactionMarkerName=None,
                              timeout=60):
    """Runs an inspector command that causes a repeatable browser driven scroll.

    Args:
      x: X coordinate of the start of the gesture in CSS pixels.
      y: Y coordinate of the start of the gesture in CSS pixels.
      xDistance: Distance to scroll along the X axis (positive to scroll left).
      yDistance: Ddistance to scroll along the Y axis (positive to scroll up).
      xOverscroll: Number of additional pixels to scroll back along the X axis.
      xOverscroll: Number of additional pixels to scroll back along the Y axis.
      preventFling: Prevents a fling gesture.
      speed: Swipe speed in pixels per second.
      gestureSourceType: Which type of input events to be generated.
      repeatCount: Number of additional repeats beyond the first scroll.
      repeatDelayMs: Number of milliseconds delay between each repeat.
      interactionMarkerName: The name of the interaction markers to generate.

    Raises:
      exceptions.TimeoutException
      exceptions.DevtoolsTargetCrashException
    """
    return self._inspector_backend.SynthesizeScrollGesture(
        x=x, y=y, xDistance=xDistance, yDistance=yDistance,
        xOverscroll=xOverscroll, yOverscroll=yOverscroll,
        preventFling=preventFling, speed=speed,
        gestureSourceType=gestureSourceType, repeatCount=repeatCount,
        repeatDelayMs=repeatDelayMs,
        interactionMarkerName=interactionMarkerName,
        timeout=timeout)
