# Copyright 2021 The Cobalt Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A module to support fundamental communications with Cobalt application."""

import enum
import json
import logging
import threading
import time

import _env  # pylint: disable=unused-import
from cobalt.tools.automated_testing import cobalt_runner
from cobalt.tools.automated_testing import webdriver_utils

webdriver_keys = webdriver_utils.import_selenium_module('webdriver.common.keys')

PERIODIC_QUERIES_INTERVAL_SECONDS = 0.1
THREAD_EXIT_TIMEOUT_SECONDS = 10
WAIT_INTERVAL_SECONDS = 0.5
WAIT_UNTIL_REACH_STATE_DEFAULT_TIMEOUT_SECONDS = 30
WAIT_UNTIL_ADS_END_DEFAULT_TIMEOUT_SECONDS = 120
WAIT_UNTIL_MEDIA_TIME_REACHED_DEFAULT_TIMEOUT_SECONDS = 30


def GetValueFromQueryResult(query_result, key, default):
  if query_result is None:
    return default

  if not isinstance(query_result, dict):
    return default

  if not query_result.has_key(key):
    return default

  value = query_result[key]
  default_value_type = type(default)
  value_type = type(value)

  if value is None:
    return default

  if value_type == default_value_type:
    return value

  if value_type in (int, float) and default_value_type in (int, float):
    return value

  # CVal returns unicode, so we need to decode them before using.
  if default_value_type in (bool, int, float):
    if value_type in (str, unicode):
      try:
        # Try to parse numbers and booleans.
        parsed_value = json.loads(value)
      except ValueError:
        raise RuntimeError('Failed to parse query result.')

      return parsed_value

  elif default_value_type is str:
    if value_type == unicode:
      return value.encode('utf-8')

  raise NotImplementedError('Convertion from (%s) to (%s) is not suppoted.' %
                            (value_type, default_value_type))


class AdditionalKeys():
  """
    Set of special keys codes for media control, corresponding to cobalt
    webdriver AdditionalSpecialKey.
  """
  MEDIA_NEXT_TRACK = u'\uf000'
  MEDIA_PREV_TRACK = u'\uf001'
  MEDIA_STOP = u'\uf002'
  MEDIA_PLAYPAUSE = u'\uf003'


class Features(enum.Enum):
  """Set of platform features."""
  SUSPEND_AND_RESUME = 1
  SEND_KEYS = 2


class ApplicationState():
  """Set of platform features."""

  def __init__(self, query_result=None):
    if not query_result is None and not isinstance(query_result, dict):
      raise NotImplementedError

    self.is_visible = GetValueFromQueryResult(query_result, 'is_visible', False)

  def __eq__(self, other):
    if not isinstance(other, self.__class__):
      raise NotImplementedError
    return self.is_visible == other.is_visible

  def __ne__(self, other):
    return not self.__eq__(other)

  @staticmethod
  def QueryJsCode():
    return """
      return {
        is_visible: document.visibilityState === "visible",
      }
    """


class ApplicationStateHandler():
  """The handler of applicatoin state."""

  def __init__(self, app):
    self.app = app
    self.state_change_handlers = []
    self.app_state = ApplicationState()

    self.app.RegisterPeriodicQuery('Application',
                                   ApplicationState.QueryJsCode(),
                                   self._ApplicatinStateQueryHandler)

  def AddAppStateChangeHandler(self, handler):
    self.state_change_handlers.append(handler)

  def RemoveAppStateChangeHandler(self, handler):
    self.state_change_handlers.remove(handler)

  def _NotifyHandlersOnStateChanged(self):
    for handler in self.state_change_handlers:
      handler(self, self.app, self.app_state)

  def _ApplicatinStateQueryHandler(self, app, query_name, query_result):
    del app, query_name  # Unused here.
    # Note that the callback is invoked on a different thread.
    new_state = ApplicationState(query_result)
    if self.app_state != new_state:
      self.app_state = new_state
      self._NotifyHandlersOnStateChanged()


class PipelinePlayerState(enum.IntEnum):
  """Set of pipeline states, equals to SbPlayerState."""
  INITIALIZED = 0  # kSbPlayerStateInitialized
  PREROLLING = 1  # kSbPlayerStatePrerolling
  PRESENTING = 2  # kSbPlayerStatePresenting
  ENDOFSTREAM = 3  # kSbPlayerStateEndOfStream
  DESTROYED = 4  # kSbPlayerStateDestroyed


class PipelineState():
  """
    The states of SbPlayerPipeline. We update the states periodically via
    webdriver and logs. Note that the duration and timestamps are in
    milliseconds.
  """

  def __init__(self, query_result=None):
    # If there's no player existing, the query return unicode code "null".
    if (not query_result is None and not query_result == u'null' and
        not isinstance(query_result, dict)):
      raise NotImplementedError

    self.identifier = GetValueFromQueryResult(query_result, 'identifier', '')
    self.is_started = GetValueFromQueryResult(query_result, 'is_started', False)
    self.is_suspended = GetValueFromQueryResult(query_result, 'is_suspended',
                                                False)
    self.is_stopped = GetValueFromQueryResult(query_result, 'is_stopped', False)
    self.is_ended = GetValueFromQueryResult(query_result, 'is_ended', False)
    self.player_state = PipelinePlayerState(
        GetValueFromQueryResult(query_result, 'player_state', 0))
    self.volume = GetValueFromQueryResult(query_result, 'volume', 1.0)
    self.playback_rate = GetValueFromQueryResult(query_result, 'playback_rate',
                                                 1.0)
    self.duration = GetValueFromQueryResult(query_result, 'duration', 0)
    self.last_media_time = GetValueFromQueryResult(query_result,
                                                   'last_media_time', 0)
    self.max_video_capabilities = GetValueFromQueryResult(
        query_result, 'max_video_capabilities', '')
    self.seek_time = GetValueFromQueryResult(query_result, 'seek_time', 0)
    self.first_written_audio_timestamp = GetValueFromQueryResult(
        query_result, 'first_written_audio_timestamp', 0)
    self.first_written_video_timestamp = GetValueFromQueryResult(
        query_result, 'first_written_video_timestamp', 0)
    self.last_written_audio_timestamp = GetValueFromQueryResult(
        query_result, 'last_written_audio_timestamp', 0)
    self.last_written_video_timestamp = GetValueFromQueryResult(
        query_result, 'last_written_video_timestamp', 0)
    self.video_width = GetValueFromQueryResult(query_result, 'video_width', 0)
    self.video_height = GetValueFromQueryResult(query_result, 'video_height', 0)
    self.is_audio_eos_written = GetValueFromQueryResult(query_result,
                                                        'is_audio_eos_written',
                                                        False)
    self.is_video_eos_written = GetValueFromQueryResult(query_result,
                                                        'is_video_eos_written',
                                                        False)
    # If |pipeline_status| is not 0, it indicates there's an error
    # in the pipeline.
    self.pipeline_status = GetValueFromQueryResult(query_result,
                                                   'pipeline_status', 0)
    self.error_message = GetValueFromQueryResult(query_result, 'error_message',
                                                 '')

  def __eq__(self, other):
    if not isinstance(other, self.__class__):
      raise NotImplementedError
    return (self.identifier == other.identifier and
            self.is_started == other.is_started and
            self.is_suspended == other.identifier and
            self.is_stopped == other.identifier and
            self.is_ended == other.is_ended and
            self.player_state == other.player_state and
            self.volume == other.volume and
            self.playback_rate == other.playback_rate and
            self.duration == other.duration and
            self.last_media_time == other.last_media_time and
            self.max_video_capabilities == other.max_video_capabilities and
            self.seek_time == other.seek_time and
            self.first_written_audio_timestamp
            == other.first_written_audio_timestamp and
            self.first_written_video_timestamp
            == other.first_written_video_timestamp and
            self.last_written_audio_timestamp
            == other.last_written_audio_timestamp and
            self.last_written_video_timestamp
            == other.last_written_video_timestamp and
            self.video_width == other.video_width and
            self.video_height == other.video_height and
            self.is_audio_eos_written == other.is_audio_eos_written and
            self.is_video_eos_written == other.is_video_eos_written and
            self.pipeline_status == other.pipeline_status and
            self.error_message == other.error_message)

  def __ne__(self, other):
    return not self.__eq__(other)

  @staticmethod
  def QueryJsCode():
    return """
      const primary_pipeline_keys = h5vcc.cVal.keys().filter(key =>
        key.startsWith("Media.Pipeline.") &&
        key.endsWith("MaxVideoCapabilities") &&
        h5vcc.cVal.getValue(key).length === 0)
      if (primary_pipeline_keys.length == 0) {
        return "null"
      }
      const key_prefix = primary_pipeline_keys[0].slice(0, -".MaxVideoCapabilities".length)
      return {
        identifier: key_prefix.slice("Media.Pipeline.".length),
        is_started: h5vcc.cVal.getValue(key_prefix + '.Started'),
        is_suspended: h5vcc.cVal.getValue(key_prefix + '.Suspended'),
        is_stopped: h5vcc.cVal.getValue(key_prefix + '.Stopped'),
        is_ended: h5vcc.cVal.getValue(key_prefix + '.Ended'),
        player_state: h5vcc.cVal.getValue(key_prefix + '.PlayerState'),
        volume: h5vcc.cVal.getValue(key_prefix + '.Volume'),
        playback_rate: h5vcc.cVal.getValue(key_prefix + '.PlaybackRate'),
        duration: h5vcc.cVal.getValue(key_prefix + '.Duration'),
        last_media_time: h5vcc.cVal.getValue(key_prefix + '.LastMediaTime'),
        max_video_capabilities: h5vcc.cVal.getValue(key_prefix + '.MaxVideoCapabilities'),
        seek_time: h5vcc.cVal.getValue(key_prefix + '.SeekTime'),
        first_written_audio_timestamp:
            h5vcc.cVal.getValue(key_prefix + '.FirstWrittenAudioTimestamp'),
        first_written_video_timestamp:
            h5vcc.cVal.getValue(key_prefix + '.FirstWrittenVideoTimestamp'),
        last_written_audio_timestamp:
            h5vcc.cVal.getValue(key_prefix + '.LastWrittenAudioTimestamp'),
        last_written_video_timestamp:
            h5vcc.cVal.getValue(key_prefix + '.LastWrittenVideoTimestamp'),
        video_width: h5vcc.cVal.getValue(key_prefix + '.VideoWidth'),
        video_height: h5vcc.cVal.getValue(key_prefix + '.VideoHeight'),
        is_audio_eos_written: h5vcc.cVal.getValue(key_prefix + '.IsAudioEOSWritten'),
        is_video_eos_written: h5vcc.cVal.getValue(key_prefix + '.IsVideoEOSWritten'),
        pipeline_status: h5vcc.cVal.getValue(key_prefix + '.PipelineStatus'),
        error_message: h5vcc.cVal.getValue(key_prefix + '.ErrorMessage'),
      }
    """

  def IsPlaying(self):
    return (len(self.identifier) > 0 and self.is_started and
            not self.is_ended and not self.is_suspended and not self.is_stopped)


class MediaSessionPlaybackState(enum.Enum):
  """Set of media session playback states."""
  NONE = 0
  PAUSED = 1
  PLAYING = 2

  # Aliases to convert string to the enum.
  none = 0
  paused = 1
  playing = 2


class MediaSessionState():
  """
    The info we get from HTML MediaSession. We update the states periodically
    via webdriver.
  """

  def __init__(self, query_result=None):
    if not query_result is None and not isinstance(query_result, dict):
      raise NotImplementedError

    metadata = None
    if isinstance(query_result, dict) and query_result.has_key('metadata'):
      metadata = query_result['metadata']

    self.title = GetValueFromQueryResult(metadata, 'title', '')
    self.artist = GetValueFromQueryResult(metadata, 'artist', '')
    self.album = GetValueFromQueryResult(metadata, 'album', '')
    self.playback_state = MediaSessionPlaybackState[GetValueFromQueryResult(
        query_result, 'playbackState', 'none')]

  def __eq__(self, other):
    if not isinstance(other, self.__class__):
      raise NotImplementedError
    return (self.title == other.title and self.artist == other.artist and
            self.album == other.album and
            self.playback_state == other.playback_state)

  def __ne__(self, other):
    if self.__eq__(other):
      return False
    return True

  @staticmethod
  def QueryJsCode():
    return """
      return {
          metadata: navigator.mediaSession.metadata,
          playbackState: navigator.mediaSession.playbackState,
        }
    """


class VideoElementState():
  """
    The info we get from HTML video element. We update the states periodically
    via webdriver.
  """

  def __init__(self, query_result=None):
    # If there's no player existing, the query return unicode code "null".
    if (not query_result is None and not query_result == u'null' and
        not isinstance(query_result, dict)):
      raise NotImplementedError

    self.has_player = isinstance(query_result, dict)
    self.current_time = GetValueFromQueryResult(query_result, 'current_time',
                                                0.0)
    self.duration = GetValueFromQueryResult(query_result, 'duration', 0.0)
    self.paused = GetValueFromQueryResult(query_result, 'paused', False)
    self.playback_rate = GetValueFromQueryResult(query_result, 'playback_rate',
                                                 0.0)
    self.volume = GetValueFromQueryResult(query_result, 'volume', 0.0)
    self.dropped_video_frames = GetValueFromQueryResult(query_result,
                                                        'dropped_video_frames',
                                                        0)
    self.total_video_frames = GetValueFromQueryResult(query_result,
                                                      'total_video_frames', 0)

  def __eq__(self, other):
    if not isinstance(other, self.__class__):
      raise NotImplementedError
    return (self.has_player == other.has_player and
            self.current_time == other.current_time and
            self.duration == other.duration and self.paused == other.paused and
            self.playback_rate == other.playback_rate and
            self.volume == other.volume and
            self.dropped_video_frames == other.dropped_video_frames and
            self.total_video_frames == other.total_video_frames)

  def __ne__(self, other):
    return not self.__eq__(other)

  @staticmethod
  def QueryJsCode():
    # Looking for a full screen video tag and return that as the primary player.
    return """
      const players = document.querySelectorAll("video");
      if (players && players.length > 0) {
        for (let i = 0; i < players.length; i++) {
          const player = players[i]
          const rect = player.getBoundingClientRect()
          if (rect.width === window.innerWidth ||
              rect.height === window.innerHeight) {
            const quality = player.getVideoPlaybackQuality();
            return {
              current_time: player.currentTime,
              duration: player.duration,
              paused: player.paused,
              playback_rate: player.playbackRate,
              volume: player.volume,
              dropped_video_frames: quality.droppedVideoFrames,
              total_video_frames: quality.totalVideoFrames,
            }
          }
        }
      }
      return "null"
    """


class PlayerStateHandler():
  """The handler of player state."""

  def __init__(self, app):
    self.app = app
    self.state_change_handlers = []
    self.player_state = type('', (), {})()
    self.player_state.pipeline_state = PipelineState()
    self.player_state.media_session_state = MediaSessionState()
    self.player_state.video_element_state = VideoElementState()

    self.app.RegisterPeriodicQuery('MediaPipeline', PipelineState.QueryJsCode(),
                                   self._PipelineStateQueryHandler)
    self.app.RegisterPeriodicQuery('MediaSession',
                                   MediaSessionState.QueryJsCode(),
                                   self._MediaSessionStateQueryHandler)
    self.app.RegisterPeriodicQuery('VideoElement',
                                   VideoElementState.QueryJsCode(),
                                   self._VideoElementStateQueryHandler)

  def AddPlayerStateChangeHandler(self, handler):
    self.state_change_handlers.append(handler)

  def RemovePlayerStateChangeHandler(self, handler):
    self.state_change_handlers.remove(handler)

  def IsPlayerPlaying(self):
    return self.player_state.pipeline_state.IsPlaying()

  def _NotifyHandlersOnStateChanged(self):
    for handler in self.state_change_handlers:
      handler(self, self.player_state)

  def _PipelineStateQueryHandler(self, app, query_name, query_result):
    # Note that the callback is invoked on a different thread.
    del app, query_name  # Unused here.
    new_state = PipelineState(query_result)
    if self.player_state.pipeline_state != new_state:
      self.player_state.pipeline_state = new_state
      self._NotifyHandlersOnStateChanged()

  def _MediaSessionStateQueryHandler(self, app, query_name, query_result):
    # Note that the callback is invoked on a different thread.
    del app, query_name  # Unused here.
    new_state = MediaSessionState(query_result)
    if self.player_state.media_session_state != new_state:
      self.player_state.media_session_state = new_state
      self._NotifyHandlersOnStateChanged()

  def _VideoElementStateQueryHandler(self, app, query_name, query_result):
    # Note that the callback is invoked on a different thread.
    del app, query_name  # Unused here.
    new_state = VideoElementState(query_result)
    if self.player_state.video_element_state != new_state:
      self.player_state.video_element_state = new_state
      self._NotifyHandlersOnStateChanged()


class AdsState(enum.IntEnum):
  """Set of ads states. The numeric values are used in ads state query."""
  NONE = 0
  PLAYING = 1
  PLAYING_AND_SKIPPABLE = 2


class TestApp():
  """
    A class encapsulating fundamental functions to control and query data
    from Cobalt application.
  """

  def __init__(self,
               launcher_params,
               url,
               supported_features,
               log_file=None,
               target_params=None,
               success_message=None):
    self.supported_features = supported_features
    self.runner = cobalt_runner.CobaltRunner(
        launcher_params=launcher_params,
        url=url,
        log_handler=self._OnNewLogLine,
        log_file=log_file,
        target_params=target_params,
        success_message=success_message)
    self.log_handlers = []
    self.is_queries_changed = False
    self.periodic_queries = {}
    self.periodic_queries_lock = threading.Lock()
    self.should_exit = threading.Event()
    self.periodic_query_thread = threading.Thread(
        target=self._RunPeriodicQueries)

    self.app_state_handler = ApplicationStateHandler(self)
    self.player_state_handler = PlayerStateHandler(self)

  def __enter__(self):
    try:
      self.runner.__enter__()
    except Exception:
      # Potentially from thread.interrupt_main(). No need to start
      # query thread.
      return self

    self.periodic_query_thread.start()
    return self

  def __exit__(self, *args):
    self.should_exit.set()
    self.periodic_query_thread.join(THREAD_EXIT_TIMEOUT_SECONDS)
    return self.runner.__exit__(*args)

  def _OnNewLogLine(self, line):
    # Note that the function is called on cobalt runner reader thread.
    # pass
    self._NotifyHandlersOnNewLogLine(line)

  def _NotifyHandlersOnNewLogLine(self, line):
    for handler in self.log_handlers:
      handler(self, line)

  def ApplicationState(self):
    return self.app_state_handler.app_state

  def PlayerState(self):
    return self.player_state_handler.player_state

  def CurrentMediaTime(self):
    # Convert timestamp from millisecond to second.
    return float(self.PlayerState().pipeline_state.last_media_time) / 1000000.0

  def Suspend(self):
    if not self.supported_features[Features.SUSPEND_AND_RESUME]:
      raise RuntimeError('Suspend is not supported.')
    if not self.runner.launcher_is_running:
      raise RuntimeError('Runner is not running.')
    self.runner.SendSystemSuspend()

  def Resume(self):
    if not self.supported_features[Features.SUSPEND_AND_RESUME]:
      raise RuntimeError('Resume is not supported.')
    if not self.runner.launcher_is_running:
      raise RuntimeError('Runner is not running.')
    self.runner.SendSystemResume()

  def SendKeys(self, keys):
    if not self.supported_features[Features.SEND_KEYS]:
      raise RuntimeError('SendKeys is not supported.')
    if not self.runner.launcher_is_running:
      raise RuntimeError('Runner is not running.')
    self.runner.SendKeys(keys)

  # The handler will receive parameters (TestApp, String).
  def AddLogHandler(self, handler):
    self.log_handlers.append(handler)

  def RemoveLogHandler(self, handler):
    self.log_handlers.remove(handler)

  # The handler will receive parameters (TestApp, ApplicationState).
  def AddAppStateChangeHandler(self, handler):
    self.app_state_handler.AddAppStateChangeHandler(handler)

  def RemoveAppStateChangeHandler(self, handler):
    self.app_state_handler.RemoveAppStateChangeHandler(handler)

  # The handler will receive parameters (TestApp, PlayerState).
  def AddPlayerStateChangeHandler(self, handler):
    self.player_state_handler.AddPlayerStateChangeHandler(handler)

  def RemovePlayerStateChangeHandler(self, handler):
    self.player_state_handler.RemoveAppStateChangeHandler(handler)

  # The handler will receive parameters (TestApp, String, Dictionary).
  def RegisterPeriodicQuery(self, query_name, query_js_code, result_handler):
    if not isinstance(query_name, str):
      raise RuntimeError('Query name must be a string.')
    if self.periodic_queries.get(query_name):
      raise RuntimeError('Duplicate query name is not allowed.')
    # TODO: Validate js code.
    with self.periodic_queries_lock:
      self.is_queries_changed = True
      self.periodic_queries[query_name] = (query_js_code, result_handler)

  def UnregisterPeriodicQuery(self, query_name):
    if not isinstance(query_name, str):
      raise RuntimeError('Query name must be a string.')
    with self.periodic_queries_lock:
      self.is_queries_changed = True
      self.periodic_queries.pop(query_name)

  def _RunPeriodicQueries(self):
    while True:
      if self.should_exit.is_set():
        break
      # Wait until webdriver client attached to Cobalt.
      if self.runner.test_script_started.is_set():
        with self.periodic_queries_lock:
          local_is_queries_changed = self.is_queries_changed
          local_periodic_queries = self.periodic_queries
          self.is_queries_changed = False
        # Skip if there's no registered query.
        if len(local_periodic_queries) == 0:
          continue
        # Generate javascript code and execute it.
        js_code = self._GeneratePeriodicQueryJsCode(local_is_queries_changed,
                                                    local_periodic_queries)
        try:
          result = self.runner.webdriver.execute_script(js_code)
        except Exception as e:
          raise RuntimeError('Periodic queries failed with error (%s)' %
                             (str(e)))

        for query_name in local_periodic_queries.keys():
          if not result.get(query_name):
            raise RuntimeError(
                'There\'s something wrong in the queries result.')
          local_periodic_queries[query_name][1](self, query_name,
                                                result[query_name])

      time.sleep(PERIODIC_QUERIES_INTERVAL_SECONDS)

  _PERIODIC_QUERIES_JS_CODE = """
    var ret = {}
    for(var key in _media_integration_testing_queries) {
      ret[key] = _media_integration_testing_queries[key]()
    }
    return ret
  """

  def _GeneratePeriodicQueryJsCode(self, is_queries_changed, periodic_queries):
    js_code = ''
    # Update registered queries at host side.
    if is_queries_changed:
      js_code += '_media_integration_testing_queries = {'
      for query_name in periodic_queries:
        js_code += query_name + ': function() {'
        js_code += periodic_queries[query_name][0]
        js_code += '},'
      js_code += '}'
    # Run queries and collect results.
    js_code += self._PERIODIC_QUERIES_JS_CODE
    return js_code

  # The first input of |state_lambda| is an instance of TestApp.
  def WaitUntilReachState(self, state_lambda, timeout=WAIT_UNTIL_REACH_STATE_DEFAULT_TIMEOUT_SECONDS):
    start_time = time.time()
    while not state_lambda(self) and time.time() - start_time < timeout:
      time.sleep(WAIT_INTERVAL_SECONDS)
    execute_interval = time.time() - start_time
    if execute_interval > timeout:
      raise RuntimeError('WaitUntilReachState timed out after (%f) seconds.' %
                         (execute_interval))

  def WaitUntilPlayerStart(self,
                           timeout=WAIT_UNTIL_REACH_STATE_DEFAULT_TIMEOUT_SECONDS
                          ):
    self.WaitUntilReachState(
        lambda _app: _app.player_state_handler.IsPlayerPlaying(), timeout)

  # TODO: Need to verify if it works without corp network.
  # TODO: Needs to recognize and skip survery.
  """
    The return values of the query, exact mapping of AdsState defined earlier
    in this file.
  """
  _GET_ADS_STATE_QUERY_JS_CODE = """
    if( document.getElementsByTagName("YTLR-AD-PREVIEW-RENDERER").length > 0 ) {
      return 1
    }
    else if( document.getElementsByTagName("YTLR-SKIP-BUTTON-RENDERER").length > 0 ) {
      return 2
    }
    return 0
  """

  def GetAdsState(self):
    if not self.runner.test_script_started.is_set():
      raise RuntimeError('Webdriver is not ready yet')
    try:
      result = self.runner.webdriver.execute_script(
          self._GET_ADS_STATE_QUERY_JS_CODE)
    except Exception as e:
      raise RuntimeError('Ads query failed with error (%s)' % (str(e)))
    return AdsState(result)

  def WaitUntilAdsEnd(self, timeout=WAIT_UNTIL_ADS_END_DEFAULT_TIMEOUT_SECONDS):
    start_time = time.time()
    # There may be multiple ads and we need to wait all of them finished.
    while time.time() - start_time < timeout:
      # Wait until the content starts, otherwise the ads state may not be right.
      self.WaitUntilReachState(lambda _app: _app.CurrentMediaTime() > 0,
                               timeout)
      ads_state = self.GetAdsState()
      if ads_state == AdsState.NONE:
        break
      while ads_state != AdsState.NONE and time.time() - start_time < timeout:
        ads_state = self.GetAdsState()
        if ads_state == AdsState.PLAYING_AND_SKIPPABLE:
          self.SendKeys(webdriver_keys.Keys.ENTER)
          logging.info('Send enter key event to skip the ad.')
        time.sleep(WAIT_INTERVAL_SECONDS)

    execute_interval = time.time() - start_time
    if execute_interval > timeout:
      raise RuntimeError(
          'WaitUntilReachState timed out after (%f) seconds, ads_state: (%d).' %
          (execute_interval, ads_state))

  def WaitUntilMediaTimeReached(
      self,
      media_time,
      timeout=WAIT_UNTIL_MEDIA_TIME_REACHED_DEFAULT_TIMEOUT_SECONDS):
    start_media_time = self.CurrentMediaTime()
    if start_media_time > media_time:
      return

    # Wait until playback starts, otherwise playback rate could be 0.
    self.WaitUntilReachState(
        lambda _app: _app.CurrentMediaTime() > start_media_time, timeout)

    playback_rate = self.PlayerState().pipeline_state.playback_rate
    if playback_rate == 0:
      raise NotImplementedError

    adjusted_timeout = (media_time -
                        self.CurrentMediaTime()) / playback_rate + timeout
    self.WaitUntilReachState(lambda _app: _app.CurrentMediaTime() > media_time,
                             adjusted_timeout)
