# Copyright 2014 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, re, time

from autotest_lib.client.common_lib import error
from autotest_lib.server.cros import vboot_constants as vboot
from autotest_lib.server.cros.faft.firmware_test import FirmwareTest
from autotest_lib.server.cros.watchdog_tester import WatchdogTester

POWER_DIR = '/var/lib/power_manager'
TMP_POWER_DIR = '/tmp/power_manager'

class firmware_EventLog(FirmwareTest):
    """
    Test to ensure eventlog is written on boot and suspend/resume.
    """
    version = 1

    _TIME_FORMAT = '%Y-%m-%d %H:%M:%S'

    def initialize(self, host, cmdline_args):
        super(firmware_EventLog, self).initialize(host, cmdline_args)
        self.host = host
        self.switcher.setup_mode('normal')
        self.setup_usbkey(usbkey=True, host=False)

    def _has_event(self, pattern):
        return bool(filter(re.compile(pattern).search, self._events))

    def _gather_events(self):
        entries = self.faft_client.system.run_shell_command_get_output(
                'mosys eventlog list')
        now = self._now()
        self._events = []
        for line in reversed(entries):
            _, time_string, event = line.split(' | ', 2)
            timestamp = time.strptime(time_string, self._TIME_FORMAT)
            if timestamp > now:
                logging.error('Found prophecy: "%s"', line)
                raise error.TestFail('Event timestamp lies in the future')
            if timestamp < self._cutoff_time:
                logging.debug('Event "%s" too early, stopping search', line)
                break
            logging.info('Found event: "%s"', line)
            self._events.append(event)

    # This assumes that Linux and the firmware use the same RTC. mosys converts
    # timestamps to localtime, and so do we (by calling date without --utc).
    def _now(self):
        time_string = self.faft_client.system.run_shell_command_get_output(
                'date +"%s"' % self._TIME_FORMAT)[0]
        logging.debug('Current local system time on DUT is "%s"', time_string)
        return time.strptime(time_string, self._TIME_FORMAT)

    def disable_suspend_to_idle(self):
        """Disable the powerd preference for suspend_to_idle."""
        logging.info('Disabling suspend_to_idle')
        # Make temporary directory to hold powerd preferences so we
        # do not leave behind any state if the test is aborted.
        self.host.run('mkdir -p %s' % TMP_POWER_DIR)
        self.host.run('echo 0 > %s/suspend_to_idle' % TMP_POWER_DIR)
        self.host.run('mount --bind %s %s' % (TMP_POWER_DIR, POWER_DIR))
        self.host.run('restart powerd')

    def teardown_powerd_prefs(self):
        """Clean up custom powerd preference changes."""
        self.host.run('umount %s' % POWER_DIR)
        self.host.run('restart powerd')

    def run_once(self):
        """Runs a single iteration of the test."""
        if not self.faft_config.has_eventlog:
            raise error.TestNAError('This board has no eventlog support.')

        logging.info('Verifying eventlog behavior on normal mode boot')
        self._cutoff_time = self._now()
        self.switcher.mode_aware_reboot()
        self.check_state((self.checkers.crossystem_checker, {
                              'devsw_boot': '0',
                              'mainfw_type': 'normal',
                              }))
        self._gather_events()
        if not self._has_event(r'System boot'):
            raise error.TestFail('No "System boot" event on normal boot.')
        # ' Wake' to match 'FW Wake' and 'ACPI Wake' but not 'Wake Source'
        if self._has_event(r'Developer Mode|Recovery Mode|Sleep| Wake'):
            raise error.TestFail('Incorrect event logged on normal boot.')

        logging.debug('Transitioning to dev mode for next test')
        self.switcher.reboot_to_mode(to_mode='dev')

        logging.info('Verifying eventlog behavior on developer mode boot')
        self._cutoff_time = self._now()
        self.switcher.mode_aware_reboot()
        self.check_state((self.checkers.crossystem_checker, {
                              'devsw_boot': '1',
                              'mainfw_type': 'developer',
                              }))
        self._gather_events()
        if (not self._has_event(r'System boot') or
            not self._has_event(r'Chrome OS Developer Mode')):
            raise error.TestFail('Missing required event on dev mode boot.')
        if self._has_event(r'Recovery Mode|Sleep| Wake'):
            raise error.TestFail('Incorrect event logged on dev mode boot.')

        logging.debug('Transitioning back to normal mode for final tests')
        self.switcher.reboot_to_mode(to_mode='normal')

        logging.info('Verifying eventlog behavior in recovery mode')
        self._cutoff_time = self._now()
        self.switcher.reboot_to_mode(to_mode='rec')
        logging.debug('Check we booted into recovery')
        self.check_state((self.checkers.crossystem_checker, {
                         'mainfw_type': 'recovery',
                         'recovery_reason' : vboot.RECOVERY_REASON['RO_MANUAL'],
                         }))
        self.switcher.mode_aware_reboot()
        self.check_state((self.checkers.crossystem_checker, {
                              'devsw_boot': '0',
                              'mainfw_type': 'normal',
                              }))
        self._gather_events()
        if (not self._has_event(r'System boot') or
            not self._has_event(r'Chrome OS Recovery Mode \| Recovery Button')):
            raise error.TestFail('Missing required event in recovery mode.')
        if self._has_event(r'Developer Mode|Sleep|FW Wake|ACPI Wake \| S3'):
            raise error.TestFail('Incorrect event logged in recovery mode.')

        logging.info('Verifying eventlog behavior on suspend/resume')
        self._cutoff_time = self._now()
        self.faft_client.system.run_shell_command(
                'powerd_dbus_suspend -wakeup_timeout=10')
        time.sleep(5)   # a little slack time for powerd to write the 'Wake'
        self._gather_events()

        # Ensure system did not log developer or recovery mode event
        if self._has_event(r'System |Developer Mode|Recovery Mode'):
            raise error.TestFail('Incorrect event logged on suspend/resume.')

        # Accept any set: Wake/Sleep, ACPI Enter/Wake S3, S0ix Enter/Exit
        if ((not self._has_event(r'^Wake') or not self._has_event(r'Sleep')) and
            (not self._has_event(r'ACPI Enter \| S3') or
             not self._has_event(r'ACPI Wake \| S3')) and
            (not self._has_event(r'S0ix Enter') or
             not self._has_event(r'S0ix Exit'))):
            # If previous attempt failed force S3 mode and try again
            logging.info('Enabling S3 to retest suspend/resume')
            self.disable_suspend_to_idle()
            self._cutoff_time = self._now()
            self.faft_client.system.run_shell_command(
                'powerd_dbus_suspend -wakeup_timeout=10')
            time.sleep(5)   # a little slack time for powerd to write the 'Wake'
            self.teardown_powerd_prefs()
            self._gather_events()
            if (not self._has_event(r'ACPI Enter \| S3') or
                not self._has_event(r'ACPI Wake \| S3')):
                raise error.TestFail('Missing required event on suspend/resume')

        watchdog = WatchdogTester(self.host)
        if not watchdog.is_supported():
            logging.info('No hardware watchdog on this platform, skipping')
        elif self.faft_client.system.run_shell_command_get_output(
                'crossystem arch')[0] != 'x86': # TODO: Implement event on x86
            logging.info('Verifying eventlog behavior with hardware watchdog')
            self._cutoff_time = self._now()
            with watchdog:
                watchdog.trigger_watchdog()
            self._gather_events()
            if (not self._has_event(r'System boot') or
                not self._has_event(r'Hardware watchdog reset')):
                raise error.TestFail('Did not log hardware watchdog event')
