"""Provides constants and functions needed by tv_testcase classes."""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import importlib
import json
import sys

# pylint: disable=C6204
from urllib import urlencode
import urlparse

import container_util

try:
  import custom_query_param_constants as query_param_constants
except ImportError:
  import default_query_param_constants as query_param_constants

# These are watched for in webdriver_benchmark_test.py
TEST_RESULT = "webdriver_benchmark TEST RESULT"
TEST_COMPLETE = "webdriver_benchmark TEST COMPLETE"

# These are event types that can be injected
EVENT_TYPE_KEY_DOWN = "KeyDown"
EVENT_TYPE_KEY_UP = "KeyUp"


def import_selenium_module(submodule=None):
  """Dynamically imports a selenium.webdriver submodule.

  This is done because selenium 3.0 is not commonly pre-installed
  on workstations, and we want to have a friendly error message for that
  case.

  Args:
    submodule: module subpath underneath "selenium.webdriver"
  Returns:
    appropriate module
  """
  if submodule:
    module_path = ".".join(("selenium", submodule))
  else:
    module_path = "selenium"
  # As of this writing, Google uses selenium 3.0.0b2 internally, so
  # thats what we will target here as well.
  try:
    module = importlib.import_module(module_path)
    if submodule is None:
      # Only the top-level module has __version__
      if not module.__version__.startswith("3.0"):
        raise ImportError("Not version 3.0.x")
  except ImportError:
    sys.stderr.write("Could not import {}\n"
                     "Please install selenium >= 3.0.0b2.\n"
                     "Commonly: \"sudo pip install 'selenium>=3.0.0b2'\"\n"
                     .format(module_path))
    sys.exit(1)
  return module


def generate_url(default_url, query_params_override=None):
  """Returns the URL indicated by the path and query parameters.

  Args:
    default_url: the default url to use; its query params may be overridden
    query_params_override: optional query params that override the ones
                           contained within the default URL
  Returns:
    the url generated from the parameters
  """
  parsed_url = list(urlparse.urlparse(default_url))

  query_params = query_param_constants.BASE_QUERY_PARAMS
  if query_params_override:
    query_params.update(query_params_override)
  else:
    query_params.update(urlparse.parse_qsl(parsed_url[4]))

  parsed_url[4] = urlencode(query_params, doseq=True)
  return urlparse.urlunparse(parsed_url)


def record_test_result(name, result):
  """Records an individual scalar result of a benchmark test.

  Args:
    name: string name of test case
    result: Test result. Must be JSON encodable scalar.
  """
  value_to_record = result

  string_value_to_record = json.JSONEncoder().encode(value_to_record)
  print("{}: {} {}\n".format(TEST_RESULT, name, string_value_to_record))
  sys.stdout.flush()


class RecordStrategyMax(object):
  """"Records the max of an array of values."""

  def run(self, name, values):
    """Records the max of an array of values.

    Args:
      name: string name of test case
      values: must be array of JSON encodable scalar
    """
    record_test_result("{}Max".format(name), max(values))


class RecordStrategyMin(object):
  """"Records the min of an array of values."""

  def run(self, name, values):
    """Records the min of an array of values.

    Args:
      name: string name of test case
      values: must be array of JSON encodable scalar
    """
    record_test_result("{}Min".format(name), min(values))


class RecordStrategyMean(object):
  """"Records the mean of an array of values."""

  def run(self, name, values):
    """Records the mean of an array of values.

    Args:
      name: string name of test case
      values: must be array of JSON encodable scalar
    """
    record_test_result("{}Mean".format(name), container_util.mean(values))


class RecordStrategyMedian(object):
  """"Records the median of an array of test results."""

  def run(self, name, values):
    """Records the median of an array of values.

    Args:
      name: string name of test case
      values: must be array of JSON encodable scalar
    """
    record_test_result("{}Median".format(name),
                       container_util.percentile(values, 50))


class RecordStrategyPercentile(object):
  """"Records the specified percentile of an array of test results."""

  def __init__(self, percentile):
    """Initializes the record strategy.

    Args:
      percentile: the percentile to record
    """
    self.percentile = percentile

  def run(self, name, values):
    """Records the percentile of an array of values.

    Args:
      name: string name of test case
      values: must be array of JSON encodable scalar
    Raises:
      RuntimeError: Raised on invalid args.
    """
    record_test_result("{}Pct{}".format(name, self.percentile),
                       container_util.percentile(values, self.percentile))


class RecordStrategyStandardDeviation(object):
  """Records the standard deviation of an array of values."""

  def run(self, name, values):
    """Records the standard deviation of an array of values.

    Args:
      name: string name of test case
      values: must be array of JSON encodable scalar
    Raises:
      RuntimeError: Raised on invalid args.
    """
    record_test_result("{}StdDev".format(name),
                       container_util.sample_standard_deviation(values))


class ResultsRecorder(object):
  """"Collects values and records results after a benchmark test ends."""

  def __init__(self, name, record_strategies):
    """Initializes the value recorder.

    Args:
      name: the name to use when recording test results
      record_strategies: the strategies to use when the test ends
    """
    self.name = name
    self.record_strategies = record_strategies
    self.values = []

  def collect_value(self, value):
    self.values.append(value)

  def on_end_test(self):
    """Handles logic related to the end of the benchmark test."""

    # Only run the strategies if values have been collected.
    if self.values:
      for record_strategy in self.record_strategies:
        record_strategy.run(self.name, self.values)
