# 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
    NEEDS_SERVO_USB = True

    _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', allow_gbb_force=True)

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