# 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 hashlib, logging, os, time


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

_DOWNLOAD_BASE = ('http://commondatastorage.googleapis.com/'
                  'chromiumos-test-assets-public/audio_power/')

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

# Measurement duration in seconds.
MEASUREMENT_DURATION = 150

POWER_DESCRIPTION = 'avg_energy_rate_'

# Time to exclude from calculation after playing audio [seconds].
STABILIZATION_DURATION = 10


class audio_PlaybackPower(test.test):
    """Captures power usage for audio playback."""

    version = 1


    def initialize(self):
        self._service_stopper = None
        self._backlight = None

    def run_power_test(self, audio_type):
        """
        Captures power usage and reports it to the perf dashboard.

        @param audio_type: audio format label to attach with perf keyval.
        """

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

        self._service_stopper = service_stopper.ServiceStopper(
                service_stopper.ServiceStopper.POWER_DRAW_SERVICES)
        self._service_stopper.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)

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

        def get_power():
            power_logger = power_status.PowerLogger(measurements)
            power_logger.start()
            time.sleep(STABILIZATION_DURATION)
            start_time = time.time()
            time.sleep(MEASUREMENT_DURATION)
            power_logger.checkpoint('result', start_time)
            keyval = power_logger.calc()
            logging.info('Power output %s', keyval)
            return keyval['result_' + measurements[0].domain + '_pwr_avg']

        energy_rate = get_power()
        perf_keyval = {}
        perf_keyval[POWER_DESCRIPTION + audio_type] = energy_rate
        self.output_perf_value(description=POWER_DESCRIPTION + audio_type,
                               value=energy_rate, units='W',
                               higher_is_better=False)
        self.write_perf_keyval(perf_keyval)


    def run_once(self, test_file, checksum):
        local_path = os.path.join(self.bindir, '%s' % test_file)
        file_utils.download_file(_DOWNLOAD_BASE + test_file, local_path)
        logging.info('Downloaded file: %s. Expected checksum: %s',
                     local_path, checksum)
        with open(local_path, 'r') as r:
            md5sum = hashlib.md5(r.read()).hexdigest()
            if md5sum != checksum:
                raise error.TestError('unmatched md5 sum: %s' % md5sum)
        with chrome.Chrome(init_network_controller=True) as cr:
            cr.browser.platform.SetHTTPServerDirectories(self.bindir)
            url = cr.browser.platform.http_server.UrlOf(local_path)
            self.play_audio(cr.browser.tabs[0], url)
            self.run_power_test(url.split('.')[-1])


    def play_audio(self, tab, url):
        """Navigates to an audio file over http and plays it in loop.

        @param tab: tab to open an audio stream.
        @param url: audio/video test url.
        """
        tab.Navigate(url)
        tab.ExecuteJavaScript(
                "document.getElementsByTagName('video')[0].loop=true")
        tab.ExecuteJavaScript(
                "document.getElementsByTagName('video')[0].volume=1")


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

        super(audio_PlaybackPower, self).cleanup()
