# 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 ast
import logging
import re
import time
from xml.parsers import expat

from autotest_lib.client.common_lib import error
from autotest_lib.client.cros import ec
from autotest_lib.server.cros.servo import servo

# Hostevent codes, copied from:
#     ec/include/ec_commands.h
HOSTEVENT_LID_CLOSED        = 0x00000001
HOSTEVENT_LID_OPEN          = 0x00000002
HOSTEVENT_POWER_BUTTON      = 0x00000004
HOSTEVENT_AC_CONNECTED      = 0x00000008
HOSTEVENT_AC_DISCONNECTED   = 0x00000010
HOSTEVENT_BATTERY_LOW       = 0x00000020
HOSTEVENT_BATTERY_CRITICAL  = 0x00000040
HOSTEVENT_BATTERY           = 0x00000080
HOSTEVENT_THERMAL_THRESHOLD = 0x00000100
HOSTEVENT_THERMAL_OVERLOAD  = 0x00000200
HOSTEVENT_THERMAL           = 0x00000400
HOSTEVENT_USB_CHARGER       = 0x00000800
HOSTEVENT_KEY_PRESSED       = 0x00001000
HOSTEVENT_INTERFACE_READY   = 0x00002000
# Keyboard recovery combo has been pressed
HOSTEVENT_KEYBOARD_RECOVERY = 0x00004000
# Shutdown due to thermal overload
HOSTEVENT_THERMAL_SHUTDOWN  = 0x00008000
# Shutdown due to battery level too low
HOSTEVENT_BATTERY_SHUTDOWN  = 0x00010000
HOSTEVENT_INVALID           = 0x80000000

# Time to wait after sending keypress commands.
KEYPRESS_RECOVERY_TIME = 0.5

# Wakemask types, copied from:
#     ec/include/ec_commands.h
EC_HOST_EVENT_MAIN = 0
EC_HOST_EVENT_B = 1
EC_HOST_EVENT_SCI_MASK = 2
EC_HOST_EVENT_SMI_MASK = 3
EC_HOST_EVENT_ALWAYS_REPORT_MASK = 4
EC_HOST_EVENT_ACTIVE_WAKE_MASK = 5
EC_HOST_EVENT_LAZY_WAKE_MASK_S0IX = 6
EC_HOST_EVENT_LAZY_WAKE_MASK_S3 = 7
EC_HOST_EVENT_LAZY_WAKE_MASK_S5 = 8


class ChromeConsole(object):
    """Manages control of a Chrome console.

    We control the Chrome console via the UART of a Servo board. Chrome console
    provides many interfaces to set and get its behavior via console commands.
    This class is to abstract these interfaces.
    """

    CMD = "_cmd"
    REGEXP = "_regexp"
    MULTICMD = "_multicmd"

    # EC Features
    # Quoted from 'enum ec_feature_code' in platform/ec/include/ec_commands.h.
    EC_FEATURE = {
        'EC_FEATURE_LIMITED'                            : 0,
        'EC_FEATURE_FLASH'                              : 1,
        'EC_FEATURE_PWM_FAN'                            : 2,
        'EC_FEATURE_PWM_KEYB'                           : 3,
        'EC_FEATURE_LIGHTBAR'                           : 4,
        'EC_FEATURE_LED'                                : 5,
        'EC_FEATURE_MOTION_SENSE'                       : 6,
        'EC_FEATURE_KEYB'                               : 7,
        'EC_FEATURE_PSTORE'                             : 8,
        'EC_FEATURE_PORT80'                             : 9,
        'EC_FEATURE_THERMAL'                            : 10,
        'EC_FEATURE_BKLIGHT_SWITCH'                     : 11,
        'EC_FEATURE_WIFI_SWITCH'                        : 12,
        'EC_FEATURE_HOST_EVENTS'                        : 13,
        'EC_FEATURE_GPIO'                               : 14,
        'EC_FEATURE_I2C'                                : 15,
        'EC_FEATURE_CHARGER'                            : 16,
        'EC_FEATURE_BATTERY'                            : 17,
        'EC_FEATURE_SMART_BATTERY'                      : 18,
        'EC_FEATURE_HANG_DETECT'                        : 19,
        'EC_FEATURE_PMU'                                : 20,
        'EC_FEATURE_SUB_MCU'                            : 21,
        'EC_FEATURE_USB_PD'                             : 22,
        'EC_FEATURE_USB_MUX'                            : 23,
        'EC_FEATURE_MOTION_SENSE_FIFO'                  : 24,
        'EC_FEATURE_VSTORE'                             : 25,
        'EC_FEATURE_USBC_SS_MUX_VIRTUAL'                : 26,
        'EC_FEATURE_RTC'                                : 27,
        'EC_FEATURE_FINGERPRINT'                        : 28,
        'EC_FEATURE_TOUCHPAD'                           : 29,
        'EC_FEATURE_RWSIG'                              : 30,
        'EC_FEATURE_DEVICE_EVENT'                       : 31,
        'EC_FEATURE_UNIFIED_WAKE_MASKS'                 : 32,
        'EC_FEATURE_HOST_EVENT64'                       : 33,
        'EC_FEATURE_EXEC_IN_RAM'                        : 34,
        'EC_FEATURE_CEC'                                : 35,
        'EC_FEATURE_MOTION_SENSE_TIGHT_TIMESTAMPS'      : 36,
        'EC_FEATURE_REFINED_TABLET_MODE_HYSTERESIS'     : 37,
        'EC_FEATURE_EFS2'                               : 38,
        'EC_FEATURE_SCP'                                : 39,
        'EC_FEATURE_ISH'                                : 40,
    }

    def __init__(self, servo, name):
        """Initialize and keep the servo object.

        Args:
          servo: A Servo object.
          name: The console name.
        """
        self.name = name
        self.uart_cmd = self.name + self.CMD
        self.uart_regexp = self.name + self.REGEXP
        self.uart_multicmd = self.name + self.MULTICMD

        self._servo = servo

    def __repr__(self):
        """Return a string representation: <ChromeConsole 'foo_uart'>"""
        return "<%s %r>" % (self.__class__.__name__, self.name)

    def set_uart_regexp(self, regexp):
        self._servo.set(self.uart_regexp, regexp)

    def clear_uart_regex(self):
        """Clear uart_regexp"""
        self.set_uart_regexp('None')

    def send_command(self, commands):
        """Send command through UART.

        This function opens UART pty when called, and then command is sent
        through UART.

        Args:
          commands: The commands to send, either a list or a string.
        """
        self.clear_uart_regex()
        if isinstance(commands, list):
            try:
                self._servo.set_nocheck(self.uart_multicmd, ';'.join(commands))
            except servo.ControlUnavailableError:
                logging.warning('The servod is too old that uart_multicmd not '
                                'supported. Use uart_cmd instead.')
                for command in commands:
                    self._servo.set_nocheck(self.uart_cmd, command)
        else:
            self._servo.set_nocheck(self.uart_cmd, commands)
        self.clear_uart_regex()

    def has_command(self, command):
        """Check whether EC console supports |command|.

        Args:
          command: Command to look for.

        Returns:
          True: If the |command| exist on the EC image of the device.
          False: If the |command| does not exist on the EC image of the device.
        """
        result = None
        try:
            # Throws error.TestFail (on timeout) if it cannot find a line with
            # 'command' in the output. Thus return False in that case.
            result = self.send_command_get_output('help', [command])
        except error.TestFail:
            return False
        return result is not None

    def send_command_get_output(self, command, regexp_list, retries=1):
        """Send command through UART and wait for response.

        This function waits for response message matching regular expressions.

        Args:
          command: The command sent.
          regexp_list: List of regular expressions used to match response
            message. Note, list must be ordered.

        Returns:
          List of tuples, each of which contains the entire matched string and
          all the subgroups of the match. None if not matched.
          For example:
            response of the given command:
              High temp: 37.2
              Low temp: 36.4
            regexp_list:
              ['High temp: (\d+)\.(\d+)', 'Low temp: (\d+)\.(\d+)']
            returns:
              [('High temp: 37.2', '37', '2'), ('Low temp: 36.4', '36', '4')]

        Raises:
          error.TestError: An error when the given regexp_list is not valid.
        """
        if not isinstance(regexp_list, list):
            raise error.TestError('Arugment regexp_list is not a list: %s' %
                                  str(regexp_list))

        while retries > 0:
            retries -= 1
            try:
                self.set_uart_regexp(str(regexp_list))
                self._servo.set_nocheck(self.uart_cmd, command)
                return ast.literal_eval(self._servo.get(self.uart_cmd))
            except (servo.UnresponsiveConsoleError,
                    servo.ResponsiveConsoleError, expat.ExpatError) as e:
                if retries <= 0:
                    raise
                logging.warning('Failed to send EC cmd. %s', e)
            finally:
                self.clear_uart_regex()


    def is_dfp(self, port=0):
        """This function checks if EC is DFP

        Args:
          port: Port of EC to check

        Returns:
          True: if EC is DFP
          False: if EC is not DFP
        """
        is_dfp = None
        ret = None
        try:
            ret = self.send_command_get_output("pd %d state" % port,
                                               ["DFP.*Flag"])
            is_dfp = True
        except Exception as e:
            is_dfp = False

        # For TCPMv1, after disconnecting a device the data state remains
        # the same, so even when pd state shows DPF, make sure the device is
        # not disconnected
        if is_dfp:
            if "DRP_AUTO_TOGGLE" in ret[0] or "DISCONNECTED" in ret[0]:
                is_dfp = False

        return is_dfp


class ChromeEC(ChromeConsole):
    """Manages control of a Chrome EC.

    We control the Chrome EC via the UART of a Servo board. Chrome EC
    provides many interfaces to set and get its behavior via console commands.
    This class is to abstract these interfaces.
    """

    # The dict to cache the battery information
    BATTERY_INFO = {}

    def __init__(self, servo, name="ec_uart"):
        super(ChromeEC, self).__init__(servo, name)

    def __repr__(self):
        """Return a string representation of the object: <ChromeEC 'ec_uart'>"""
        return "<%s %r>" % (self.__class__.__name__, self.name)

    def key_down(self, keyname):
        """Simulate pressing a key.

        Args:
          keyname: Key name, one of the keys of KEYMATRIX.
        """
        self.send_command('kbpress %d %d 1' %
                (ec.KEYMATRIX[keyname][1], ec.KEYMATRIX[keyname][0]))


    def key_up(self, keyname):
        """Simulate releasing a key.

        Args:
          keyname: Key name, one of the keys of KEYMATRIX.
        """
        self.send_command('kbpress %d %d 0' %
                (ec.KEYMATRIX[keyname][1], ec.KEYMATRIX[keyname][0]))


    def key_press(self, keyname):
        """Press and then release a key.

        Args:
          keyname: Key name, one of the keys of KEYMATRIX.
        """
        self.send_command([
                'kbpress %d %d 1' %
                    (ec.KEYMATRIX[keyname][1], ec.KEYMATRIX[keyname][0]),
                'kbpress %d %d 0' %
                    (ec.KEYMATRIX[keyname][1], ec.KEYMATRIX[keyname][0]),
                ])
        # Don't spam the EC console as fast as we can; leave some recovery time
        # in between commands.
        time.sleep(KEYPRESS_RECOVERY_TIME)


    def send_key_string_raw(self, string):
        """Send key strokes consisting of only characters.

        Args:
          string: Raw string.
        """
        for c in string:
            self.key_press(c)


    def send_key_string(self, string):
        """Send key strokes including special keys.

        Args:
          string: Character string including special keys. An example
            is "this is an<tab>example<enter>".
        """
        for m in re.finditer("(<[^>]+>)|([^<>]+)", string):
            sp, raw = m.groups()
            if raw is not None:
                self.send_key_string_raw(raw)
            else:
                self.key_press(sp)


    def reboot(self, flags=''):
        """Reboot EC with given flags.

        Args:
          flags: Optional, a space-separated string of flags passed to the
                 reboot command, including:
                   default: EC soft reboot;
                   'hard': EC hard/cold reboot;
                   'ap-off': Leave AP off after EC reboot (by default, EC turns
                             AP on after reboot if lid is open).

        Raises:
          error.TestError: If the string of flags is invalid.
        """
        for flag in flags.split():
            if flag not in ('hard', 'ap-off'):
                raise error.TestError(
                        'The flag %s of EC reboot command is invalid.' % flag)
        self.send_command("reboot %s" % flags)


    def set_flash_write_protect(self, enable):
        """Set the software write protect of EC flash.

        Args:
          enable: True to enable write protect, False to disable.
        """
        if enable:
            self.send_command("flashwp enable")
        else:
            self.send_command("flashwp disable")


    def set_hostevent(self, codes):
        """Set the EC hostevent codes.

        Args:
          codes: Hostevent codes, HOSTEVENT_*
        """
        self.send_command("hostevent set %#x" % codes)
        # Allow enough time for EC to process input and set flag.
        # See chromium:371631 for details.
        # FIXME: Stop importing time module if this hack becomes obsolete.
        time.sleep(1)


    def enable_console_channel(self, channel):
        """Find console channel mask and enable that channel only

        @param channel: console channel name
        """
        # The 'chan' command returns a list of console channels,
        # their channel masks and channel numbers
        regexp = r'(\d+)\s+([\w]+)\s+\*?\s+{0}'.format(channel)
        l = self.send_command_get_output('chan', [regexp])
        # Use channel mask and append the 0x for proper hex input value
        cmd = 'chan 0x' + l[0][2]
        # Set console to only output the desired channel
        self.send_command(cmd)


    def get_version(self):
        """Get version information from the Chrome EC console.
           Additionally, can be used to verify if EC console is available.
        """
        self.send_command("chan 0")
        # Use "[ \t]" here and not \s because sometimes the version is blank,
        # i.e. 'RO:   \r\n' which matches RO:\s+
        expected_output = [
                "Chip:[ \t]+([^\r\n]*)\r\n", "RO:[ \t]+([^\r\n]*)\r\n",
                "RW_?[AB]?:[ \t]+([^\r\n]*)\r\n", "Build:[ \t]+([^\r\n]*)\r\n"
        ]
        l = self.send_command_get_output("version", expected_output)
        self.send_command("chan 0xffffffff")
        return l

    def check_ro_rw(self, img_exp):
        """Tell if the current EC image matches the given input, 'RW' or 'RO.

        Args:
            img_exp: Expected image type. It should be either 'RW' or 'RO'.
        Return:
            True if the active EC image matches to 'img_exp'.
            False otherwise.
        Raise:
            TestError if img_exp is neither 'RW' nor 'RO'.
        """
        if img_exp not in ['RW', 'RO']:
            raise error.TestError('Arugment img_exp is neither RW nor RO')

        result = self.send_command_get_output('sysinfo', [r'Copy:\s*(RO|RW)'])
        return result[0][1] == img_exp

    def check_feature(self, feature):
        """Return true if EC supports the given feature

        Args:
            feature: feature name as a string as in self.EC_FEATURE.

        Returns:
            True if 'feature' is in EC's feature set.
            False otherwise
        """
        feat_id = self.EC_FEATURE[feature]
        if feat_id < 32:
            feat_start = 0
        else:
            feat_start = 32

        regexp = r'%d-%d:\s*(0x[0-9a-fA-F]{8})' % (feat_start,
                                                   feat_start + 31)

        try:
            result = self.send_command_get_output('feat', [regexp])
        except servo.ResponsiveConsoleError as e:
            logging.warn("feat command is not available: %s", str(e))
            return False

        feat_bitmap = int(result[0][1], 16)

        return ((1 << (feat_id - feat_start)) & feat_bitmap) != 0

    def update_battery_info(self):
        """Get the battery info we care for this test."""
        # The battery parameters we care for this test. The order must match
        # the output of EC battery command.
        battery_params = [
                'V', 'V-desired', 'I', 'I-desired', 'Charging', 'Remaining'
        ]
        regex_str_list = []

        for p in battery_params:
            if p == 'Remaining':
                regex_str_list.append(p + ':\s+(\d+)\s+')
            elif p == 'Charging':
                regex_str_list.append(p + r':\s+(Not Allowed|Allowed)\s+')
            else:
                regex_str_list.append(p +
                                      r':\s+0x[0-9a-f]*\s+=\s+([0-9-]+)\s+')

        # For unknown reasons, servod doesn't always capture the ec
        # command output. It doesn't happen often, but retry if it does.
        retries = 3
        while retries > 0:
            retries -= 1
            try:
                battery_regex_match = self.send_command_get_output(
                        'battery', regex_str_list)
                break
            except (servo.UnresponsiveConsoleError,
                    servo.ResponsiveConsoleError) as e:
                if retries <= 0:
                    raise
                logging.warning('Failed to get battery status. %s', e)
        else:
            battery_regex_match = self.send_command_get_output(
                    'battery', regex_str_list)

        for i in range(len(battery_params)):
            if battery_params[i] == 'Charging':
                self.BATTERY_INFO[
                        battery_params[i]] = battery_regex_match[i][1]
            else:
                self.BATTERY_INFO[battery_params[i]] = int(
                        battery_regex_match[i][1])
        logging.debug('Battery info: %s', self.BATTERY_INFO)

    def get_battery_desired_voltage(self, print_result=True):
        """Get battery desired voltage value."""
        if not self.BATTERY_INFO:
            self.update_battery_info()
        if print_result:
            logging.info('Battery desired voltage = %d mV',
                         self.BATTERY_INFO['V-desired'])
        return self.BATTERY_INFO['V-desired']

    def get_battery_desired_current(self, print_result=True):
        """Get battery desired current value."""
        if not self.BATTERY_INFO:
            self.update_battery_info()
        if print_result:
            logging.info('Battery desired current = %d mA',
                         self.BATTERY_INFO['I-desired'])
        return self.BATTERY_INFO['I-desired']

    def get_battery_actual_voltage(self, print_result=True):
        """Get the actual voltage from charger to battery."""
        if not self.BATTERY_INFO:
            self.update_battery_info()
        if print_result:
            logging.info('Battery actual voltage = %d mV',
                         self.BATTERY_INFO['V'])
        return self.BATTERY_INFO['V']

    def get_battery_actual_current(self, print_result=True):
        """Get the actual current from charger to battery."""
        if not self.BATTERY_INFO:
            self.update_battery_info()
        if print_result:
            logging.info('Battery actual current = %d mA',
                         self.BATTERY_INFO['I'])
        return self.BATTERY_INFO['I']

    def get_battery_remaining(self, print_result=True):
        """Get battery charge remaining in mAh."""
        if not self.BATTERY_INFO:
            self.update_battery_info()
        if print_result:
            logging.info("Battery charge remaining = %d mAh",
                         self.BATTERY_INFO['Remaining'])
        return self.BATTERY_INFO['Remaining']

    def get_battery_charging_allowed(self, print_result=True):
        """Get the battery charging state.

        Returns True if charging is allowed.
        """
        if not self.BATTERY_INFO:
            self.update_battery_info()
        if print_result:
            logging.info("Battery charging = %s",
                         self.BATTERY_INFO['Charging'])
        if self.BATTERY_INFO['Charging'] == 'Allowed':
            return True
        return False


class ChromeUSBPD(ChromeEC):
    """Manages control of a Chrome USBPD.

    We control the Chrome EC via the UART of a Servo board. Chrome USBPD
    provides many interfaces to set and get its behavior via console commands.
    This class is to abstract these interfaces.
    """

    def __init__(self, servo):
        super(ChromeUSBPD, self).__init__(servo, "usbpd_uart")
