# Copyright (c) 2011 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 collections, logging, os

from autotest_lib.client.bin import test, utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import rtc, sys_power

# TODO(tbroch) General:
# - What other Ethernet Capabilities should we check

# TODO(tbroch) WOL:
# - Should we test any of the other modes?  I chose magic as it meant that only
#   the target device should be awaken.
class network_EthCaps(test.test):
    version = 1

    # If WOL setting changed during test then restore to original during cleanup
    _restore_wol = False


    def _parse_ethtool_caps(self):
        """Retrieve ethernet capabilities.

        Executes ethtool command and parses various capabilities into a
        dictionary.
        """
        caps = collections.defaultdict(list)

        cmd = "ethtool %s" % self._ethname
        prev_keyname = None
        for ln in utils.system_output(cmd).splitlines():
            cap_str = ln.strip()
            try:
                (keyname, value) = cap_str.split(': ')
                caps[keyname].extend(value.split())
                prev_keyname = keyname
            except ValueError:
                # keyname from previous line, add there
                if prev_keyname:
                    caps[prev_keyname].extend(cap_str.split())

        for keyname in caps:
            logging.debug("cap['%s'] = %s", keyname, caps[keyname])

        self._caps = caps


    def _check_eth_caps(self):
        """Check necessary LAN capabilities are present.

        Hardware and driver should support the following functionality:
          1000baseT, 100baseT, 10baseT, half-duplex, full-duplex, auto-neg, WOL

        Raises:
          error.TestError if above LAN capabilities are NOT supported.
        """
        default_eth_caps = {
            'Supported link modes': ['10baseT/Half', '100baseT/Half',
                                      '1000baseT/Half', '10baseT/Full',
                                      '100baseT/Full', '1000baseT/Full'],
            'Supports auto-negotiation': ['Yes'],
            # TODO(tbroch): Will this order, 'pumbg' remain across other h/w +
            # drivers
            # TODO(tbroch): Other WOL caps: 'a': arp and 's': magicsecure are
            # they important?  Are any of these undesirable/security holes?
            'Supports Wake-on': ['pumbg']
            }
        errors = 0

        for keyname in default_eth_caps:
            if keyname not in self._caps:
                logging.error("\'%s\' not a capability of %s", keyname,
                              self._ethname)
                errors += 1
                continue

            for value in default_eth_caps[keyname]:
                if value not in self._caps[keyname]:
                    logging.error("\'%s\' not a supported mode in \'%s\' of %s",
                                  value, keyname, self._ethname)
                    errors += 1

        if errors:
            raise error.TestError("Eth capability checks.  See errors")


    def _test_wol_magic_packet(self):
        """Check the Wake-on-LAN (WOL) magic packet capabilities of a device.

        Raises:
          error.TestError if WOL functionality fails
        """
        # Magic number WOL supported
        capname = 'Supports Wake-on'
        if self._caps[capname][0].find('g') != -1:
            logging.info("%s support magic number WOL", self._ethname)
        else:
            raise error.TestError('%s should support magic number WOL' %
                            self._ethname)

        # Check that WOL works
        if self._caps['Wake-on'][0] != 'g':
            utils.system_output("ethtool -s %s wol g" % self._ethname)
            self._restore_wol = True

        # Set RTC as backup to WOL
        before_suspend_secs = rtc.get_seconds()
        alarm_secs =  before_suspend_secs + self._threshold_secs * 2
        rtc.set_wake_alarm(alarm_secs)

        sys_power.suspend_to_ram()

        after_suspend_secs = rtc.get_seconds()
        # flush RTC as it may not work subsequently if wake was not RTC
        rtc.set_wake_alarm(0)

        suspend_secs = after_suspend_secs - before_suspend_secs
        if suspend_secs > self._threshold_secs:
            raise error.TestError("Device woke due to RTC not WOL")


    def _verify_wol_magic(self):
        """If possible identify wake source was caused by WOL.

        The bits identifying this may be cleared by the time kernel/userspace
        gets a change to query.  However if the firmware has a log it may expose
        the wake source.  This method attempts to interrogate the wake source
        details if they are present on the system.

        Returns:
          True if verified or unable to verify due to system limitations
          False otherwise
        """
        cmd = "mosys smbios info bios"
        bios_info = utils.system_output(cmd).replace(' ', '').split('|')
        logging.debug("bios_info = %s", bios_info)
        if 'coreboot' not in bios_info:
            logging.warn("Unable to verify wake in s/w due to firmware type")
            if 'INSYDE' not in bios_info:
                raise error.TestError("Unrecognized firmware found")
            return True

        fw_log = "/sys/firmware/log"
        if not os.path.isfile(fw_log):
            logging.warn("Unable to verify wake in s/w due to missing log %s",
                         fw_log)
            return True

        log_info_str = utils.system_output("egrep '(SMI|PM1|GPE0)_STS:' %s" %
                                           fw_log)
        status_dict = {}
        for ln in log_info_str.splitlines():
            logging.debug("f/w line = %s", ln)
            try:
                (status_reg, status_values) = ln.strip().split(":")
                status_dict[status_reg] = status_values.split()
            except ValueError:
                # no bits asserted ... empty list
                status_dict[status_reg] = list()

        for status_reg in status_dict:
            logging.debug("status_dict[%s] = %s", status_reg,
                          status_dict[status_reg])

        return ('PM1' in status_dict['SMI_STS']) and \
            ('WAK' in status_dict['PM1_STS']) and \
            ('PCIEXPWAK' in status_dict['PM1_STS']) and \
            len(status_dict['GPE0_STS']) == 0


    def cleanup(self):
        if self._restore_wol:
            utils.system_output("ethtool -s %s wol %s" %
                                (self._ethname, self._caps['Wake-on'][0]))


    def run_once(self, ethname=None, threshold_secs=None):
        """Run the test.

        Args:
          ethname: string of ethernet device under test
          threshold_secs: integer of seconds to determine whether wake occurred
            due to WOL versus RTC
        """
        if not ethname:
            raise error.TestError("Name of ethernet device must be declared")

        self._ethname = ethname
        self._threshold_secs = threshold_secs

        self._parse_ethtool_caps()
        self._check_eth_caps()
        self._test_wol_magic_packet()
        # TODO(tbroch) There is evidence in the filesystem of the wake source
        # for coreboot but its still being flushed out.  For now only produce a
        # warning for this check.
        if not self._verify_wol_magic():
            logging.warning("Unable to see evidence of WOL wake in filesystem")
