# Copyright 2019 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.

"""Server side bluetooth adapter stress tests involving power consumption."""

import logging
import multiprocessing
import time

from autotest_lib.client.common_lib import error
from autotest_lib.server.cros.bluetooth.bluetooth_adapter_tests import (
        test_case_log)
from autotest_lib.server.cros.bluetooth.bluetooth_adapter_quick_tests import (
        BluetoothAdapterQuickTests)


class bluetooth_AdapterPowerMeasure(BluetoothAdapterQuickTests):
    """Server side bluetooth adapter power consumption test."""

    test_wrapper = BluetoothAdapterQuickTests.quick_test_test_decorator
    batch_wrapper = BluetoothAdapterQuickTests.quick_test_batch_decorator


    def _check_legitimate_board(self):
        """Check if this is a legitimate board to run the test.

        Only a limited set of boards are supported for now, primarily
        the kukui family of barods.

        @raises: TestNAError if the board is not legitimate.

        """
        board = self.host.get_board().split(':')[1]
        if board not in ('kukui'):
            raise error.TestNAError('%s not legitimate to run the test.' %
                                    board)


    def _initialize_servod(self, device):
        """Perform initialize for servod task.

        @param device: the peer device

        @raises: TestError if not able to enable or start servo.
        """
        self.count_fail_to_sleep = 0
        self.count_fail_to_resume = 0
        self.count_system_resume_prematurely = 0
        self.count_success = 0

        # When the autotest restarts ui, chrome would issue some Bluetooth
        # commands which may prevent the system from suspending properly.
        # Hence, let's stop ui for now.
        self.host.run_short('stop ui')

        board = self.host.get_board().split(':')[1]
        logging.info('board: %s', board)

        # TODO(b/152737849): figure out a way to support more boards.
        self._check_legitimate_board()

        # device is a pure XMLRPC server running as chameleond
        # on the bluetooth peer. We need to enable Servod.
        if not device.EnableServod(board):
            raise error.TestError('Failed to enable Servod.')

        # Start the Servod process on the bluetooth peer.
        if not device.servod.Start():
            raise error.TestError('Failed to start Servod on bluetooth peer.')


    def _cleanup_servod(self, device):
        """Perform cleanup for servod.

        @param device: the peer device
        """
        if not device.servod.Stop():
            logging.error('Failed to stop Servod on bluetooth peer.')

        self.host.run_short('start ui')

        logging.info('count_fail_to_sleep: %d', self.count_fail_to_sleep)
        logging.info('count_fail_to_resume: %d', self.count_fail_to_resume)
        logging.info('count_system_resume_prematurely: %d',
                     self.count_system_resume_prematurely)
        logging.info('count_success: %d', self.count_success)


    # ---------------------------------------------------------------
    # Definitions of test cases
    # ---------------------------------------------------------------

    @test_case_log
    def test_case_suspend_power_measurement(self, host, device, max_power_mw,
                                            suspend_time_secs,
                                            resume_network_timeout_secs=60):
        """Test Case: measure the Bluetooth chip power consumption on suspend"""

        def print_debug_count():
            """Print the debug message about count values."""
            logging.debug('count_fail_to_sleep: %d', self.count_fail_to_sleep)
            logging.debug('count_fail_to_resume: %d', self.count_fail_to_resume)
            logging.debug('count_system_resume_prematurely: %d',
                          self.count_system_resume_prematurely)
            logging.debug('count_success: %d', self.count_success)

        def action_suspend():
            """Calls the host method suspend."""
            host.suspend(suspend_time=suspend_time_secs,
                         allow_early_resume=True)

        boot_id = host.get_boot_id()
        proc = multiprocessing.Process(target=action_suspend)
        proc.daemon = True
        start_time = time.time()
        proc.start()

        # Block waiting until the system has suspended.
        try:
            host.test_wait_for_sleep(suspend_time_secs)
        except Exception as e:
            logging.error('host.test_wait_for_sleep failed: %s', e)
            self.count_fail_to_sleep += 1
            print_debug_count()
            # Skip this time since the system failed to suspend.
            proc.join()
            return

        # Test the Bluetooth chip power consumption.
        if self.test_power_consumption(device, max_power_mw):
            self.count_success += 1

        # Block waiting until the system has resumed.
        try:
            host.test_wait_for_resume(
                    boot_id, suspend_time_secs + resume_network_timeout_secs)
        except Exception as e:
            logging.error('host.test_wait_for_resume failed: %s', e)
            self.count_fail_to_resume += 1

        # If the system resumes prematurely, do not conduct the test in
        # this iteration.
        actual_suspend_time_secs = time.time() - start_time
        if actual_suspend_time_secs < suspend_time_secs:
            logging.error('actual suspension time %f is less than expected %f',
                          actual_suspend_time_secs, suspend_time_secs)
            self.count_system_resume_prematurely += 1

        print_debug_count()
        proc.join()

        if self.count_success == 0:
            raise error.TestError('System failed to suspend/resume.')


    # ---------------------------------------------------------------
    # Definitions of test wrapper tests and batch wrapper tests.
    # ---------------------------------------------------------------


    @test_wrapper('Power measurement test', devices={'BLUETOOTH_BASE':1})
    def pw_measurement_suspension_test(self):
        """power measurement test during system suspension."""
        device = self.devices['BLUETOOTH_BASE'][0]
        self._initialize_servod(device)
        self.test_power_on_adapter()
        self.test_bluetoothd_running()
        self.test_case_suspend_power_measurement(self.host, device,
                                                 self.max_power_mw,
                                                 self.suspend_time_secs)
        self._cleanup_servod(device)


    @batch_wrapper('Bluetooth Power Measurement Sanity Tests')
    def pw_sanity_batch_run(self, num_iterations=1, test_name=None):
        """Run bluetooth power measurement sanity test batch or a specific test.

        @param num_iterations: how many iterations to run
        @param test_name: specific test to run otherwise None to run the
                whole batch
        """
        self.pw_measurement_suspension_test()


    def run_once(self, host, num_iterations=1, test_name=None,
                 max_power_mw=3, suspend_time_secs=30, flag='Quick Sanity'):
        """Running Bluetooth adapter power consumption autotest during system
        suspension.

        @param host: the DUT host.
        @param num_iterations: number of times to perform the tests.
        @param test_name: the test to run, or None for all tests
        @param max_power_mw: max power allowed in milli-watt
        @param suspend_time_secs: the system suspension duration in seconds

        """
        self.host = host
        self.max_power_mw = max_power_mw
        self.suspend_time_secs = suspend_time_secs

        self.quick_test_init(host, use_btpeer=True, flag=flag)
        self.pw_sanity_batch_run(num_iterations, test_name)
        self.quick_test_cleanup()
