# Copyright 2014 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.

# This file defines performance test scenarios related to playing video and
# audio files using HTML5 APIs (as opposed to older tech like Flash and
# Silverlight). These scenarios simply exercise the Chromium code in particular
# ways. The metrics that are produced are calculated in a separate step.

import abc

from telemetry.page import page as page_module
from telemetry.page import traffic_setting as traffic_setting_module
from telemetry import story

# A complete list of page tags to check. This prevents misspellings and provides
# documentation of scenarios for code readers. These tags can be used to filter
# the list of pages to run using flags like --story-tag-filter=X.
_PAGE_TAGS_LIST = [
    # Audio codecs.
    'pcm',
    'mp3',
    'aac',
    'vorbis',
    'opus',
    # Video codecs.
    'av1',
    'h264',
    'vp8',
    'vp9',
    # Test types.
    'audio_video',
    'audio_only',
    'video_only',
    # Other filter tags.
    'is_50fps',
    'is_4k',
    # Play action.
    'seek',
    'beginning_to_end',
    'background',
    # Add javascript load.
    'busyjs',
    # Constrained network settings.
    'cns',
    # VideoStack API.
    'src',
    'mse'
]


# A list of traffic setting names to append to page names when used.
# Traffic settings is a way to constrain the network to match real-world
# scenarios.
_TRAFFIC_SETTING_NAMES = {
    traffic_setting_module.GPRS: 'GPRS',
    traffic_setting_module.REGULAR_2G: 'Regular-2G',
    traffic_setting_module.GOOD_2G: 'Good-2G',
    traffic_setting_module.REGULAR_3G: 'Regular-3G',
    traffic_setting_module.GOOD_3G: 'Good-3G',
    traffic_setting_module.REGULAR_4G: 'Regular-4G',
    traffic_setting_module.DSL: 'DSL',
    traffic_setting_module.WIFI: 'WiFi',
}

_URL_BASE = 'file://media_cases/'

#
# The following section contains base classes for pages.
#

class _MediaPage(page_module.Page):

  def __init__(self, url, page_set, tags, extra_browser_args=None,
               traffic_setting=traffic_setting_module.NONE):
    name = url.split('/')[-1]
    if traffic_setting != traffic_setting_module.NONE:
      name += '_' + _TRAFFIC_SETTING_NAMES[traffic_setting]
      tags.append('cns')
    if tags:
      for t in tags:
        assert t in _PAGE_TAGS_LIST
    assert not ('src' in tags and 'mse' in tags)
    super(_MediaPage, self).__init__(
        url=url, page_set=page_set, tags=tags, name=name,
        extra_browser_args=extra_browser_args,
        traffic_setting=traffic_setting)


class _BeginningToEndPlayPage(_MediaPage):
  """A normal play page simply plays the given media until the end."""

  def __init__(self, url, page_set, tags, extra_browser_args=None,
               traffic_setting=traffic_setting_module.NONE):
    tags.append('beginning_to_end')
    tags.append('src')
    super(_BeginningToEndPlayPage, self).__init__(
        url, page_set, tags, extra_browser_args,
        traffic_setting=traffic_setting)

  def RunPageInteractions(self, action_runner):
    # Play the media until it has finished or it times out.
    action_runner.PlayMedia(playing_event_timeout_in_seconds=60,
                            ended_event_timeout_in_seconds=60)
    # Generate memory dump for memoryMetric.
    if self.page_set.measure_memory:
      action_runner.MeasureMemory()


class _SeekPage(_MediaPage):
  """A seek page seeks twice in the video and measures the seek time."""

  def __init__(self, url, page_set, tags, extra_browser_args=None,
               action_timeout_in_seconds=60,
               traffic_setting=traffic_setting_module.NONE):
    tags.append('seek')
    tags.append('src')
    self._action_timeout = action_timeout_in_seconds
    super(_SeekPage, self).__init__(
        url, page_set, tags, extra_browser_args,
        traffic_setting=traffic_setting)

  def RunPageInteractions(self, action_runner):
    timeout = self._action_timeout
    # Start the media playback.
    action_runner.PlayMedia(
        playing_event_timeout_in_seconds=timeout)
    # Wait for 1 second so that we know the play-head is at ~1s.
    action_runner.Wait(1)
    # Seek to before the play-head location.
    action_runner.SeekMedia(seconds=0.5, timeout_in_seconds=timeout,
                            label='seek_warm')
    # Seek to after the play-head location.
    action_runner.SeekMedia(seconds=9, timeout_in_seconds=timeout,
                            label='seek_cold')
    # Generate memory dump for memoryMetric.
    if self.page_set.measure_memory:
      action_runner.MeasureMemory()


class _BackgroundPlaybackPage(_MediaPage):
  """A Background playback page plays the given media in a background tab.

  The motivation for this test case is crbug.com/678663.
  """

  def __init__(self, url, page_set, tags, extra_browser_args=None,
               background_time=10,
               traffic_setting=traffic_setting_module.NONE):
    self._background_time = background_time
    tags.append('background')
    tags.append('src')
    # disable-media-suspend is required since for Android background playback
    # gets suspended. This flag makes Android work the same way as desktop and
    # not turn off video playback in the background.
    extra_browser_args = extra_browser_args or []
    extra_browser_args.append('--disable-media-suspend')
    super(_BackgroundPlaybackPage, self).__init__(
        url, page_set, tags, extra_browser_args)

  def RunPageInteractions(self, action_runner):
    # Steps:
    # 1. Play a video
    # 2. Open new tab overtop to obscure the video
    # 3. Close the tab to go back to the tab that is playing the video.
    action_runner.PlayMedia(
        playing_event_timeout_in_seconds=60)
    action_runner.Wait(.5)
    new_tab = action_runner.tab.browser.tabs.New()
    new_tab.Activate()
    action_runner.Wait(self._background_time)
    new_tab.Close()
    action_runner.Wait(.5)
    # Generate memory dump for memoryMetric.
    if self.page_set.measure_memory:
      action_runner.MeasureMemory()


class _MSEPage(_MediaPage):

  def __init__(self, url, page_set, tags, extra_browser_args=None,
               number_of_runs=10):
    assert number_of_runs >= 1
    self._number_of_runs = number_of_runs
    tags.append('mse')
    super(_MSEPage, self).__init__(
        url, page_set, tags, extra_browser_args)

  def RunPageInteractions(self, action_runner):
    # The page automatically runs the test at load time.
    self._CheckTestResult(action_runner)
    # Now run it a few more times to get more reliable data.
    # Note that each run takes ~.5s, so running a bunch of times to get reliable
    # data is reasonable.
    for _ in range(self._number_of_runs - 1):
      url = action_runner.tab.url
      action_runner.tab.ClearCache(force=True)
      action_runner.tab.Navigate(url)
      self._CheckTestResult(action_runner)

  def _CheckTestResult(self, action_runner):
    action_runner.WaitForJavaScriptCondition('window.__testDone == true')
    test_failed = action_runner.EvaluateJavaScript('window.__testFailed')
    if test_failed:
      raise RuntimeError(action_runner.EvaluateJavaScript('window.__testError'))


def _GetDesktopOnlyMediaPages(page_set):
  return [
        _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=tulip0.av1.mp4',
          page_set=page_set,
          tags=['av1', 'video_only']),
        _SeekPage(
          url=_URL_BASE + 'video.html?src=tulip0.av1.mp4&seek',
          page_set=page_set,
          tags=['av1', 'video_only', 'seek']),
        _MSEPage(
          url=_URL_BASE + 'mse.html?media=tulip0.av1.mp4',
          page_set=page_set,
          tags=['av1', 'video_only']),
        ]


def _GetCrossPlatformMediaPages(page_set):
  return [
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=crowd.ogg&type=audio',
          page_set=page_set,
          tags=['vorbis', 'audio_only']),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=crowd1080.webm',
          page_set=page_set,
          tags=['is_50fps', 'vp8', 'vorbis', 'audio_video']),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=tulip2.ogg&type=audio',
          page_set=page_set,
          tags=['vorbis', 'audio_only']),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=tulip2.wav&type=audio',
          page_set=page_set,
          tags=['pcm', 'audio_only']),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=crowd1080.mp4',
          page_set=page_set,
          tags=['is_50fps', 'h264', 'aac', 'audio_video']),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=tulip2.mp3&type=audio',
          page_set=page_set,
          tags=['mp3', 'audio_only']),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=tulip2.mp4',
          page_set=page_set,
          tags=['h264', 'aac', 'audio_video']),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=tulip2.m4a&type=audio',
          page_set=page_set,
          tags=['aac', 'audio_only']),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=garden2_10s.webm',
          page_set=page_set,
          tags=['is_4k', 'vp8', 'vorbis', 'audio_video']),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=garden2_10s.mp4',
          page_set=page_set,
          tags=['is_4k', 'h264', 'aac', 'audio_video']),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=tulip2.vp9.webm',
          page_set=page_set,
          tags=['vp9', 'opus', 'audio_video'],
          traffic_setting=traffic_setting_module.WIFI),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=tulip2.vp9.webm',
          page_set=page_set,
          tags=['vp9', 'opus', 'audio_video']),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=crowd1080_vp9.webm',
          page_set=page_set,
          tags=['vp9', 'video_only']),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=crowd720_vp9.webm',
          page_set=page_set,
          tags=['vp9', 'video_only']),
      _BeginningToEndPlayPage(
          url=_URL_BASE + 'video.html?src=tulip2.mp4&busyjs',
          page_set=page_set,
          tags=['h264', 'aac', 'audio_video', 'busyjs']),
      _SeekPage(
          url=_URL_BASE + 'video.html?src=tulip2.ogg&type=audio&seek',
          page_set=page_set,
          tags=['vorbis', 'audio_only']),
      _SeekPage(
          url=_URL_BASE + 'video.html?src=tulip2.wav&type=audio&seek',
          page_set=page_set,
          tags=['pcm', 'audio_only']),
      _SeekPage(
          url=_URL_BASE + 'video.html?src=tulip2.mp3&type=audio&seek',
          page_set=page_set,
          tags=['mp3', 'audio_only']),
      _SeekPage(
          url=_URL_BASE + 'video.html?src=tulip2.mp4&seek',
          page_set=page_set,
          tags=['h264', 'aac', 'audio_video']),
      _SeekPage(
          url=_URL_BASE + 'video.html?src=garden2_10s.webm&seek',
          page_set=page_set,
          tags=['is_4k', 'vp8', 'vorbis', 'audio_video']),
      _SeekPage(
          url=_URL_BASE + 'video.html?src=garden2_10s.mp4&seek',
          page_set=page_set,
          tags=['is_4k', 'h264', 'aac', 'audio_video']),
      _SeekPage(
          url=_URL_BASE + 'video.html?src=tulip2.vp9.webm&seek',
          page_set=page_set,
          tags=['vp9', 'opus', 'audio_video']),
      _SeekPage(
          url=_URL_BASE + 'video.html?src=crowd1080_vp9.webm&seek',
          page_set=page_set,
          tags=['vp9', 'video_only', 'seek']),
      _SeekPage(
          url=(_URL_BASE + 'video.html?src='
               'smpte_3840x2160_60fps_vp9.webm&seek'),
          page_set=page_set,
          tags=['is_4k', 'vp9', 'video_only'],
          action_timeout_in_seconds=120),
      _BackgroundPlaybackPage(
          url=_URL_BASE + 'video.html?src=tulip2.vp9.webm&background',
          page_set=page_set,
          tags=['vp9', 'opus', 'audio_video']),
      _MSEPage(
          url=_URL_BASE + 'mse.html?media=aac_audio.mp4,h264_video.mp4',
          page_set=page_set,
          tags=['h264', 'aac', 'audio_video']),
      _MSEPage(
          url=(_URL_BASE + 'mse.html?'
               'media=aac_audio.mp4,h264_video.mp4&waitForPageLoaded=true'),
          page_set=page_set,
          tags=['h264', 'aac', 'audio_video']),
      _MSEPage(
          url=_URL_BASE + 'mse.html?media=aac_audio.mp4',
          page_set=page_set,
          tags=['aac', 'audio_only']),
      _MSEPage(
          url=_URL_BASE + 'mse.html?media=h264_video.mp4',
          page_set=page_set,
          tags=['h264', 'video_only']),
      ]


class _MediaCasesStorySet(story.StorySet):
  """Abstract Media Cases Story Set to be overriden."""
  def __init__(self, measure_memory=False):
    super(_MediaCasesStorySet, self).__init__(
            cloud_storage_bucket=story.PARTNER_BUCKET)
    self.measure_memory = measure_memory
    for page in self._BuildPages():
      self.AddStory(page)

  @abc.abstractmethod
  def _BuildPages(self):
    """Subclasses should implement this to return an iterator of pages."""


class MediaCasesDesktopStorySet(_MediaCasesStorySet):
  """
  Description: Video Stack Perf pages that report time_to_play, seek time and
  many other media-specific and generic metrics.
  """
  def _BuildPages(self):
    return iter(
        _GetCrossPlatformMediaPages(self) + _GetDesktopOnlyMediaPages(self))


class MediaCasesMobileStorySet(_MediaCasesStorySet):
  """
  Description: Video Stack Perf pages that report time_to_play, seek time and
  many other media-specific and generic metrics.

  The mobile story set removes stories that are too difficult for mobile
  devices.
  """
  def _BuildPages(self):
    for page in _GetCrossPlatformMediaPages(self):
      if 'is_4k' in page.tags or 'is_50fps' in page.tags:
        continue
      yield page
