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

from contextlib import closing
import logging
import os
import time
import urllib2

from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import chrome
from autotest_lib.client.cros import power_status, power_utils
from autotest_lib.client.cros import service_stopper


# Chrome flags to use fake camera and skip camera permission.
EXTRA_BROWSER_ARGS = ['--use-fake-device-for-media-stream',
                      '--use-fake-ui-for-media-stream']
NO_WEBRTC_HARDWARE_ACCELERATION_BROWSER_ARGS = ['--disable-webrtc-hw-decoding',
                                                '--disable-webrtc-hw-encoding']

FAKE_FILE_ARG = '--use-file-for-fake-video-capture="%s"'
DOWNLOAD_BASE = 'http://commondatastorage.googleapis.com/chromiumos-test-assets-public/crowd/'
VIDEO_NAME = 'crowd720_25frames.y4m'

WEBRTC_INTERNALS_URL = 'chrome://webrtc-internals'
RTC_INIT_HISTOGRAM = 'Media.RTCVideoDecoderInitDecodeSuccess'
HISTOGRAMS_URL = 'chrome://histograms/' + RTC_INIT_HISTOGRAM

# Minimum battery charge percentage we prefer to run the test
BATTERY_INITIAL_CHARGED_MIN = 10

WEBRTC_WITH_HARDWARE_ACCELERATION = 'webrtc_with_hardware_acceleration'
WEBRTC_WITHOUT_HARDWARE_ACCELERATION = 'webrtc_without_hardware_acceleration'

# Measure duration in seconds
MEASURE_DURATION = 120
# Time to exclude from calculation after firing a task [seconds].
STABILIZATION_DURATION = 5

class video_WebRtcPower(test.test):
    """The test outputs the power consumption for WebRTC to performance
    dashboard.
    """
    version = 1

    def initialize(self):
        # Objects that need to be taken care of in cleanup() are initialized
        # here to None. Otherwise we run the risk of AttributeError raised in
        # cleanup() masking a real error that caused the test to fail during
        # initialize() before those variables were assigned.
        self._backlight = None

        self._services = service_stopper.ServiceStopper(
            service_stopper.ServiceStopper.POWER_DRAW_SERVICES)
        self._services.stop_services()

        self._power_status = power_status.get_status()
        # Verify that we are running on battery and the battery is
        # sufficiently charged.
        self._power_status.assert_battery_state(BATTERY_INITIAL_CHARGED_MIN)


    def start_loopback(self, cr):
        """
        Opens WebRTC loopback page.

        @param cr: Autotest Chrome instance.
        """
        tab = cr.browser.tabs[0]
        tab.Navigate(cr.browser.http_server.UrlOf(
                os.path.join(self.bindir, 'loopback.html')))
        tab.WaitForDocumentReadyStateToBeComplete()


    def assert_hardware_accelerated(self, cr, is_hardware_accelerated):
        """
        Checks if WebRTC decoding is hardware accelerated.

        @param cr: Autotest Chrome instance.
        @param is_hardware_accelerated: if is_hardware_accelerated is True then
        assert hardware accelerated otherwise assert hardware not accelerated.

        @raises error.TestError if decoding is not hardware accelerated while
        is_hardware_accelerated is True or if decoding is hardware accelerated
        while is_hardware_accelerated is False.
        """
        tab = cr.browser.tabs.New()
        def histograms_loaded():
            """Returns true if histogram is loaded."""
            tab.Navigate(HISTOGRAMS_URL)
            tab.WaitForDocumentReadyStateToBeComplete()
            return tab.EvaluateJavaScript(
                    'document.documentElement.innerText.search("%s") != -1'
                    % RTC_INIT_HISTOGRAM)

        try:
            utils.poll_for_condition(
                    histograms_loaded,
                    timeout=5,
                    exception=error.TestError(
                            'Cannot find rtc video decoder histogram.'),
                    sleep_interval=1)
        except error.TestError as e:
            if is_hardware_accelerated:
                raise e
        else:
            if not is_hardware_accelerated:
                raise error.TestError(
                        'Video decode acceleration shoud not be working.')
            if tab.EvaluateJavaScript(
                    'document.documentElement.innerText.search('
                    '"1 = 100.0%") == -1'):
                raise error.TestError(
                        'Video decode acceleration is not working.')

        tab.Close()


    def run_once(self):
        # Download test video.
        url = DOWNLOAD_BASE + VIDEO_NAME
        local_path = os.path.join(self.bindir, VIDEO_NAME)
        self.download_file(url, local_path)

        self._backlight = power_utils.Backlight()
        self._backlight.set_default()

        measurements = [power_status.SystemPower(
                self._power_status.battery_path)]
        self._power_logger = power_status.PowerLogger(measurements)
        self._power_logger.start()

        # Run the WebRTC tests.
        self.test_webrtc(local_path)

        keyvals = self._power_logger.calc()
        measurement_type = '_' + measurements[0].domain + '_pwr'
        energy_rate_with_hw = keyvals[WEBRTC_WITH_HARDWARE_ACCELERATION +
                                      measurement_type]
        self.output_perf_value(
                description='webrtc_energy_rate.mean',
                value=energy_rate_with_hw,
                units='W', higher_is_better=False)
        # Save the results to the autotest results directory
        self._power_logger.save_results(self.resultsdir)

        # Find the energy of full battery
        batinfo = self._power_status.battery[0]
        self.energy_full_design = batinfo.energy_full_design
        logging.info("energy_full_design = %0.3f Wh",
                     self.energy_full_design)

        logging.info('Expected battery life using WebRtc with'
                     'hardware acceleration : %0.3f hours',
                     self.energy_full_design / energy_rate_with_hw)

        energy_rate_without_hw = keyvals[WEBRTC_WITHOUT_HARDWARE_ACCELERATION +
                                         measurement_type]
        logging.info('Expected battery life using WebRtc without'
                     'hardware acceleration : %0.3f hours',
                     self.energy_full_design / energy_rate_without_hw)


    def test_webrtc(self, local_path):
        """
        Runs the WebRTC test with and without hardware acceleration.

        @param local_path: the path to the video file.
        @param test_duration: test duration for a run (seconds).
        """
        EXTRA_BROWSER_ARGS.append(FAKE_FILE_ARG % local_path)
        with chrome.Chrome(extra_browser_args=EXTRA_BROWSER_ARGS) as cr:
            # Open WebRTC loopback page.
            cr.browser.SetHTTPServerDirectories(self.bindir)
            self.start_loopback(cr)

            # Make sure decode is hardware accelerated.
            self.assert_hardware_accelerated(cr, True)

            # Record the start time and the end time of this power
            # measurement test run.
            time.sleep(STABILIZATION_DURATION)
            start_time = time.time()
            time.sleep(MEASURE_DURATION)
            self._power_logger.checkpoint(WEBRTC_WITH_HARDWARE_ACCELERATION,
                                          start_time)

        # Start chrome with test flag
        # and disabled WebRTC hardware encode and decode flag.
        with chrome.Chrome(extra_browser_args=EXTRA_BROWSER_ARGS +
                           NO_WEBRTC_HARDWARE_ACCELERATION_BROWSER_ARGS) as cr:

            # Open WebRTC loopback page.
            cr.browser.SetHTTPServerDirectories(self.bindir)
            self.start_loopback(cr)

            # Make sure decode is not hardware accelerated.
            self.assert_hardware_accelerated(cr, False)

            # Record the start time and the end time of this power
            # measurement test run.
            time.sleep(STABILIZATION_DURATION)
            start_time = time.time()
            time.sleep(MEASURE_DURATION)
            self._power_logger.checkpoint(WEBRTC_WITHOUT_HARDWARE_ACCELERATION,
                                          start_time)


    def download_file(self, url, local_path):
        """
        Downloads a file from the specified URL.

        @param url: URL of the file.
        @param local_path: the path that the file will be saved to.
        """
        logging.info('Downloading "%s" to "%s"', url, local_path)
        with closing(urllib2.urlopen(url)) as r, open(local_path, 'wb') as w:
            w.write(r.read())


    def cleanup(self):
        # cleanup() is run by common_lib/test.py.
        if self._backlight:
            self._backlight.restore()
        if self._services:
            self._services.restore_services()

        super(video_WebRtcPower, self).cleanup()
