# Copyright (c) 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.

"""Extended WebDriver interface that uses helper extension.

This file is makeshift and should eventually be switched over to
using the new ChromeDriver python interface. However, as that is
not quite ready, this class simply installs a helper extension
and executes scripts in the background page to access extension
APIs.

This may end up being merged with chrome/test/ext_auto, if they
accomplish similar enough purposes. For now, integration with that
is a bit premature.
"""

import os

from selenium import webdriver


_CHROME_GET_VIEW_HANDLES = 'chrome.getViewHandles'
_EXTENSION = os.path.join(
    os.path.dirname(os.path.abspath(__file__)), 'ext_auto')


class Chrome(webdriver.Remote):
  """Extended WebDriver interface that uses helper extension."""

  def __init__(self, url, desired_capabilities):
    switches = desired_capabilities.get('chrome.switches', [])
    switches += ['--load-extension=' + _EXTENSION]
    desired_capabilities['chrome.switches'] = switches
    super(Chrome, self).__init__(url, desired_capabilities)

    custom_commands = {
        _CHROME_GET_VIEW_HANDLES:
            ('GET', '/session/$sessionId/chrome/views'),
    }
    self.command_executor._commands.update(custom_commands)
    views = self.execute(_CHROME_GET_VIEW_HANDLES)['value']
    self.set_script_timeout(30)  # TODO(kkania): Make this configurable.
    for view in views:
      if view.get('extension_id') == 'aapnijgdinlhnhlmodcfapnahmbfebeb':
        self._extension = view['handle']
        break
    else:
      raise RuntimeError('Unable to find helper extension')

  def _execute_extension_command(self, name, params={}):
    """Executes an extension command.

    When Chrome is started, a helper extension is loaded which provides
    a simple synchronous API for manipulating Chrome via the extension
    APIs. Communication with the extension is accomplished by executing
    a script in the background page of the extension which calls the
    'executeCommand' function with the name of the command, a parameter
    dictionary, and a callback function that can be used to signal
    when the command is finished and potentially send a return value.
    """
    old_window = self.current_window_handle
    self.switch_to_window(self._extension)
    self.execute_async_script(
        'executeCommand.apply(null, arguments)', name, params)
    self.switch_to_window(old_window)

  def create_tab(self, url=None):
    """Creates a new tab with the given URL and switches to it.

    If no URL is provided, the homepage will be used.
    """
    params = {}
    if url is not None:
      params['url'] = url
    self._execute_extension_command('createTab', params)
    self.switch_to_window(self.window_handles[-1])

  def create_blank_tab(self):
    """Creates a new blank tab and switches to it."""
    self.create_tab('about:blank')
