# 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.server.cros.faft.firmware_test import FirmwareTest


class firmware_ECBootTime(FirmwareTest):
    """
    Servo based EC boot time test.
    """
    version = 1

    def initialize(self, host, cmdline_args):
        super(firmware_ECBootTime, self).initialize(host, cmdline_args)
        # Don't bother if there is no Chrome EC.
        if not self.check_ec_capability():
            raise error.TestNAError("Nothing needs to be tested on this device")
        # Only run in normal mode
        self.switcher.setup_mode('normal')
        self.host = host

    def check_boot_time(self):
        """Check EC and AP boot times"""
        # Initialize a list of two strings, one printed by the EC when the AP
        # is taken out of reset, and another one printed when the EC observes
        # the AP running. These strings are used as for console output anchors
        # when calculating the AP boot time.
        #
        # This is very approximate, a better long term solution would be to
        # have the EC print the same fixed strings for these two events on all
        # platforms. http://crosbug.com/p/21628 has been opened to track this
        # issue.
        if self._x86:
            boot_anchors = ["\[([0-9\.]+) PB",
                            "\[([0-9\.]+) [^\r\n]*(HC 0x|Port 80|ACPI query)"]
        elif self._arm_legacy:
            boot_anchors = ["\[([0-9\.]+) AP running ...",
                            "\[([0-9\.]+) XPSHOLD seen"]
        else:
            boot_anchors = ["\[([0-9\.]+) power state 1 = S5",
                            "\[([0-9\.]+) power state 3 = S0"]

        # regular expression to say that EC is ready. For systems that
        # run out of ram there is a second boot where the PMIC is
        # asked to power cycle the EC to be 100% sure (I wish) that
        # the code is clean. Looking for the "Inits done" or "VB Exit"
        # generates a match after the first boot, and introduces a
        # race between the EC booting the second time and the test
        # sending the power_cmd.
        if self._doubleboot:
            ec_ready = ["(?ms)UART.*UART.*?\[([0-9.]+) "]
        else:
            ec_ready = ["([0-9.]+) (Inits done|VB Exit)"]

        if self.faft_config.ec_has_powerbtn_cmd:
            # powerbtn takes ms while hold_pwr_button_powero is seconds.
            hold_ms = int(1000 * self.faft_config.hold_pwr_button_poweron)
            power_cmd = 'powerbtn %s' % hold_ms
        else:
            power_cmd = 'power on'

        # Try the EC reboot command several times in case the console
        # output is not clean enough for the full string to be found.
        retry = 10
        while retry > 0:
            retry = retry - 1
            try:
                reboot = self.ec.send_command_get_output(
                    "reboot ap-off", ec_ready)
                break
            except error.TestFail:
                logging.info("Unable to parse EC console output, "
                             "%d more attempts", retry)
        if retry == 0:
            raise error.TestFail("Unable to reboot EC cleanly, " +
                                 "Please try removing AC power")
        logging.debug("reboot: %r", reboot)

        # The EC console must be available 1 second after startup
        time.sleep(1)

        version = self.ec.get_version()

        if not version:
            raise error.TestFail("Unable to get EC console.")

        # Wait until the ap enter the G3
        time.sleep(self.faft_config.ec_reboot_to_g3_delay)

        # Enable printing host commands. Some boards have it disabled by default
        # After reboot it will be restored to default
        self.ec.send_command("hcdebug normal")

        # Enable port80 output for x86 devices so there is an early signal from
        # the host that it is booting, instead of relying on an EC transaction.
        if self._x86:
            self.ec.send_command("port80 intprint")

        # Switch on the AP
        power_press = self.ec.send_command_get_output(
            power_cmd, boot_anchors)

        # TODO(crbug.com/847289): reboot_time only measures the time spent in
        # EC's main function, which is not a good measure of "EC cold boot time"
        reboot_time = float(reboot[0][1])
        power_press_time = float(power_press[0][1])
        firmware_resp_time = float(power_press[1][1])
        boot_time = firmware_resp_time - power_press_time
        logging.info("EC cold boot time: %f s", reboot_time)
        if reboot_time > 1.0:
            raise error.TestFail("EC cold boot time longer than 1 second.")
        logging.info("EC boot time: %f s", boot_time)
        if boot_time > 1.0:
            raise error.TestFail("Boot time longer than 1 second.")

    def is_arm_legacy_board(self):
        """Detect whether the board is a legacy ARM board.

        This group of boards prints specific strings on the EC console when the
        EC and AP come out of reset.
        """

        arm_legacy = ('snow', 'spring', 'pit', 'pi', 'big', 'blaze', 'kitty')
        output = self.faft_client.system.get_platform_name()
        return output.lower() in arm_legacy

    def run_once(self):
        """Execute the main body of the test.
        """

        self._x86 = ('x86' in self.faft_config.ec_capability)
        self._doubleboot = ('doubleboot' in self.faft_config.ec_capability)
        self._arm_legacy = self.is_arm_legacy_board()
        logging.info("Reboot and check EC cold boot time and host boot time.")
        self.switcher.mode_aware_reboot('custom', self.check_boot_time)

    def cleanup(self):
        try:
            # Restore the ec_uart_regexp to None
            self.ec.set_uart_regexp('None')

            # Reboot the EC and wait for the host to come up so it is ready for
            # the next test.
            self.ec.reboot()
            self.host.wait_up(timeout=30)
        except Exception as e:
            logging.error("Caught exception: %s", str(e))
        super(firmware_ECBootTime, self).cleanup()
