# 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.
import logging

from telemetry.page import test_expectations
from telemetry.page.actions import all_page_actions
from telemetry.page.actions import interact
from telemetry.page.actions import navigate
from telemetry.page.actions import page_action


def _GetActionFromData(action_data):
  action_name = action_data['action']
  action = all_page_actions.FindClassWithName(action_name)
  if not action:
    logging.critical('Could not find an action named %s.', action_name)
    logging.critical('Check the page set for a typo and check the error '
                     'log for possible Python loading/compilation errors.')
    raise Exception('Action "%s" not found.' % action_name)
  return action(action_data)


def GetSubactionFromData(page, subaction_data, interactive):
  subaction_name = subaction_data['action']
  if hasattr(page, subaction_name):
    return GetCompoundActionFromPage(page, subaction_name, interactive)
  else:
    return [_GetActionFromData(subaction_data)]


def GetCompoundActionFromPage(page, action_name, interactive=False):
  if interactive:
    return [interact.InteractAction()]

  if not action_name:
    return []

  action_data_list = getattr(page, action_name)
  if not isinstance(action_data_list, list):
    action_data_list = [action_data_list]

  action_list = []
  for subaction_data in action_data_list:
    for _ in xrange(subaction_data.get('repeat', 1)):
      action_list += GetSubactionFromData(page, subaction_data, interactive)
  return action_list


class Failure(Exception):
  """Exception that can be thrown from PageMeasurement to indicate an
  undesired but designed-for problem."""
  pass


class PageTest(object):
  """A class styled on unittest.TestCase for creating page-specific tests."""

  def __init__(self,
               test_method_name,
               action_name_to_run='',
               needs_browser_restart_after_each_page=False,
               discard_first_result=False,
               clear_cache_before_each_run=False,
               attempts=3,
               max_failures=None,
               max_errors=None):
    self.options = None
    try:
      self._test_method = getattr(self, test_method_name)
    except AttributeError:
      raise ValueError, 'No such method %s.%s' % (
        self.__class_, test_method_name)  # pylint: disable=E1101
    self._action_name_to_run = action_name_to_run
    self._needs_browser_restart_after_each_page = (
        needs_browser_restart_after_each_page)
    self._discard_first_result = discard_first_result