# Copyright 2015 The Chromium OS 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 datetime, time

from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros.video import method_logger


class VideoPlayer(object):
    """
    Provides interface to interact with and control video playback via js.

    Specific players such as VimeoPlayer will inherit from this class and
    customize its behavior.

    """


    def __init__(self, tab, full_url, video_id, video_src_path='',
                 event_timeout=5, polling_wait_time=1):
        """
        @param tab: object, tab to interact with the tab in the browser.
        @param full_url: string, full url pointing to html file to load.
        @param video_src_path: path, complete path to video used for test.
        @param video_id: string, name of the video_id element in the html file.
        @param time_out_for_events_s: integer, how long to wait for an event
                                      before timing out
        @param time_btwn_polling_s: integer, how long to wait between one call
                                    to check a condition and the next.

        """
        self.tab = tab
        self.full_url = full_url
        self.video_id = video_id
        self.video_src_path = video_src_path
        self.event_timeout = event_timeout
        self.polling_wait_time = polling_wait_time
        self.tab.Navigate(self.full_url)


    @method_logger.log
    def load_video(self, wait_for_canplay=True):
        """
        Loads video into browser.
        @param wait_for_canplay: video will be verified before play

        """
        self.tab.WaitForDocumentReadyStateToBeComplete()
        self.wait_for_script_ready()
        time.sleep(2)
        self.inject_source_file()
        if wait_for_canplay:
             self.wait_for_video_ready()


    def inject_source_file(self):
        """
        Injects source file into html file if needed.

        Created for subclasses that need it

        """
        pass


    @method_logger.log
    def wait_for_script_ready(self):
        """
        Wait for Javascript variables and functions to be defined.

        """
        exception_msg = 'Script did not ready in time.'

        self._wait_for_event(self.is_javascript_ready, exception_msg)


    @method_logger.log
    def wait_for_video_ready(self):
        """
        Waits for video to signal that is ready.

        Each class that inherits from this will define its is_video_ready
        function.

        """
        exception_msg = 'Video did not signal ready in time.'

        self._wait_for_event(self.is_video_ready, exception_msg)


    @method_logger.log
    def verify_video_can_play(self, duration=0):
        """
        Plays video and ensures that reported video current time is > 0.

        @param duration: duration to play a video
        @raises: error.TestError if current time is not > 0 after time > 0s

        """
        exception_msg = 'Expected current time >%ds.' %duration

        self.play()

        # check that video is playing
        self._wait_for_event(
                  lambda : self.currentTime() > duration, exception_msg)

        self.pause()

        # seek back to the beginning of video
        self.seek_to(datetime.timedelta(seconds=0))


    @method_logger.log
    def seek_to(self, timestamp):
        """
        Uses javascript to set currentTime property of video to desired time.

        @param timestamp: timedelta, instance of time to navigate video to.

        """
        self.seek_to(timestamp)


    @method_logger.log
    def wait_for_video_to_seek(self):
        """
        Waits for video's currentTime to equal the time it was seeked to.

        """
        exception_msg = 'Video did not complete seeking in time.'

        self._wait_for_event(self.has_video_finished_seeking, exception_msg)

        # it usually takes a little while before new frame renders, so wait
        time.sleep(1)


    @method_logger.log
    def _wait_for_event(self, predicate_function, exception_msg):
        """
         Helper method to wait for a desired condition.

         @param predicate_function: object, function which returns true when
                                    desired condition is achieved.
         @param exception_msg: string, an exception message to show when desired
                               condition is not achieved in allowed time.

        """
        fullmsg = exception_msg + ' Waited for %ss' % self.event_timeout

        utils.poll_for_condition(predicate_function,
                                 error.TestError(fullmsg),
                                 self.event_timeout,
                                 self.polling_wait_time)
