# 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']

        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()
