# Lint as: python2, python3
# Copyright (c) 2012 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 logging
import time

from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib.cros import chrome
from autotest_lib.client.cros.bluetooth import bluetooth_device_xmlrpc_server
from autotest_lib.client.cros.input_playback import keyboard
from autotest_lib.client.cros.power import power_test
from autotest_lib.client.cros.power import power_utils


class power_Idle(power_test.power_Test):
    """class for power_Idle test.

    Collects power stats when machine is idle

    Current tests,

      | test# | seconds | display   | bluetooth |
      -------------------------------------------
      | 1     | 120     | off       | off       |
      | 2     | 120     | default   | off       |
      | 3     | 120     | default   | on - idle |
      | 4     | 120     | off       | on - idle |

    """
    version = 1
    first_test_warmup_secs = 60

    def initialize(self, pdash_note='', seconds_period=10.,
                   force_discharge=False, run_arc=True):
        super(power_Idle, self).initialize(seconds_period=seconds_period,
                                           pdash_note=pdash_note,
                                           force_discharge=force_discharge,
                                           run_arc=run_arc)

    def run_once(self, warmup_secs=20, idle_secs=120, default_only=False):
        """Collect power stats for idle tests."""

        def measure_it(warmup_secs, idle_secs, tagname):
            """Helper function to wrap testing loop for each sub test."""
            if self.is_first_test:
                warmup_secs += self.first_test_warmup_secs
                self.is_first_test = False
            if warmup_secs > 0:
                tstart = time.time()
                time.sleep(warmup_secs)
                self.checkpoint_measurements("warmup", tstart)
            tstart = time.time()
            time.sleep(idle_secs)
            self.checkpoint_measurements(tagname, tstart)

        bt_device = bluetooth_device_xmlrpc_server \
            .BluetoothDeviceXmlRpcDelegate()

        # --disable-sync disables test account info sync, eg. Wi-Fi credentials,
        # so that each test run does not remember info from last test run.
        extra_browser_args = ['--disable-sync']
        # b/228256145 to avoid powerd restart
        extra_browser_args.append('--disable-features=FirmwareUpdaterApp')
        with chrome.Chrome(extra_browser_args=extra_browser_args,
                           arc_mode=self._arc_mode) as self.cr:
            self.is_first_test = True

            # Measure power in full-screen blank tab
            tab = self.cr.browser.tabs.New()
            tab.Activate()
            fullscreen = tab.EvaluateJavaScript('document.webkitIsFullScreen')
            if not fullscreen:
                with keyboard.Keyboard() as keys:
                    keys.press_key('f4')

            # Stop services again as Chrome might have restarted them.
            self._services.stop_services()

            if default_only:
                self.start_measurements()
                measure_it(warmup_secs, idle_secs, 'all-default')
                return

            # test1 : display off, BT off
            power_utils.set_display_power(power_utils.DISPLAY_POWER_ALL_OFF)
            if not bt_device.set_powered(False):
                raise error.TestFail('Cannot turn off bluetooth adapter.')
            self.start_measurements()
            measure_it(warmup_secs, idle_secs, 'display-off_bluetooth-off')

            # test2 : display default, BT off
            power_utils.set_display_power(power_utils.DISPLAY_POWER_ALL_ON)
            measure_it(warmup_secs, idle_secs,
                       'display-default_bluetooth-off')

            # test3 : display default, BT on
            if not bt_device.set_powered(True):
                logging.warning('Cannot turn on bluetooth adapter.')
                return
            measure_it(warmup_secs, idle_secs, 'display-default_bluetooth-on')

            # test4 : display off, BT on
            power_utils.set_display_power(power_utils.DISPLAY_POWER_ALL_OFF)
            measure_it(warmup_secs, idle_secs, 'display-off_bluetooth-on')

    def cleanup(self):
        """Reset to previous state."""
        power_utils.set_display_power(power_utils.DISPLAY_POWER_ALL_ON)
        super(power_Idle, self).cleanup()
