# 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 glob, logging, os, re, shutil
from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error


# Possible display power settings. Copied from chromeos::DisplayPowerState
# in Chrome's dbus service constants.
DISPLAY_POWER_ALL_ON = 0
DISPLAY_POWER_ALL_OFF = 1
DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON = 2
DISPLAY_POWER_INTERNAL_ON_EXTERNAL_OFF = 3
# for bounds checking
DISPLAY_POWER_MAX = 4


def get_x86_cpu_arch():
    """Identify CPU architectural type.

    Intel's processor naming conventions is a mine field of inconsistencies.
    Armed with that, this method simply tries to identify the architecture of
    systems we care about.

    TODO(tbroch) grow method to cover processors numbers outlined in:
        http://www.intel.com/content/www/us/en/processors/processor-numbers.html
        perhaps returning more information ( brand, generation, features )

    Returns:
      String, explicitly (Atom, Core, Celeron) or None
    """
    cpuinfo = utils.read_file('/proc/cpuinfo')

    if re.search(r'Intel.*Atom.*[NZ][2-6]', cpuinfo):
        return 'Atom'
    if re.search(r'Intel.*Celeron.*N2[89][0-9][0-9]', cpuinfo):
        return 'Celeron N2000'
    if re.search(r'Intel.*Celeron.*N3[0-9][0-9][0-9]', cpuinfo):
        return 'Celeron N3000'
    if re.search(r'Intel.*Celeron.*[0-9]{3,4}', cpuinfo):
        return 'Celeron'
    if re.search(r'Intel.*Core.*i[357]-[234][0-9][0-9][0-9]', cpuinfo):
        return 'Core'

    logging.info(cpuinfo)
    return None


def has_rapl_support():
    """Identify if platform supports Intels RAPL subsytem.

    Returns:
        Boolean, True if RAPL supported, False otherwise.
    """
    cpu_arch = get_x86_cpu_arch()
    if cpu_arch and ((cpu_arch is 'Celeron') or (cpu_arch is 'Core')):
        return True
    return False


def _call_dbus_method(destination, path, interface, method_name, args):
    """Performs a generic dbus method call."""
    command = ('dbus-send --type=method_call --system '
               '--dest=%s %s %s.%s %s') % (destination, path, interface,
               method_name, args)
    utils.system_output(command)


def call_powerd_dbus_method(method_name, args=''):
    """
    Calls a dbus method exposed by powerd.

    Arguments:
    @param method_name: name of the dbus method.
    @param args: string containing args to dbus method call.
    """
    _call_dbus_method(destination='org.chromium.PowerManager',
                      path='/org/chromium/PowerManager',
                      interface='org.chromium.PowerManager',
                      method_name=method_name, args=args)

def call_chrome_dbus_method(method_name, args=''):
    """
    Calls a dbus method exposed by chrome.

    Arguments:
    @param method_name: name of the dbus method.
    @param args: string containing args to dbus method call.
    """
    _call_dbus_method(destination='org.chromium.LibCrosService',
                      path='/org/chromium/LibCrosService',
                      interface='org.chomium.LibCrosServiceInterface',
                      method_name=method_name, args=args)


class BacklightException(Exception):
    """Class for Backlight exceptions."""


class Backlight(object):
    """Class for control of built-in panel backlight.

    Public methods:
       set_level: Set backlight level to the given brightness.
       set_percent: Set backlight level to the given brightness percent.
       set_resume_level: Set backlight level on resume to the given brightness.
       set_resume_percent: Set backlight level on resume to the given brightness
                           percent.
       set_default: Set backlight to CrOS default.

       get_level: Get backlight level currently.
       get_max_level: Get maximum backight level.
       get_percent: Get backlight percent currently.
       restore: Restore backlight to initial level when instance created.

    Public attributes:
        default_brightness_percent: float of default brightness

    Private methods:
        _try_bl_cmd: run a backlight command.

    Private attributes:
        _init_level: integer of backlight level when object instantiated.
        _can_control_bl: boolean determining whether backlight can be controlled
                         or queried
    """
    # Default brightness is based on expected average use case.
    # See http://www.chromium.org/chromium-os/testing/power-testing for more
    # details.
    def __init__(self, default_brightness_percent=0):
        """Constructor.

        attributes:
        """
        cmd = "mosys psu type"
        result = utils.system_output(cmd, ignore_status=True).strip()
        self._can_control_bl = not result == "AC_only"

        self._init_level = self.get_level()
        self.default_brightness_percent = default_brightness_percent

        logging.debug("device can_control_bl: %s", self._can_control_bl)
        if not self._can_control_bl:
            return

        if not self.default_brightness_percent:
            cmd = "get_powerd_initial_backlight_level 2>/dev/null"
            try:
                level = float(utils.system_output(cmd).rstrip())
                self.default_brightness_percent = \
                    (level / self.get_max_level()) * 100
                logging.info("Default backlight brightness percent = %f",
                             self.default_brightness_percent)
            except error.CmdError:
                self.default_brightness_percent = 40.0
                logging.warning("Unable to determine default backlight "
                             "brightness percent.  Setting to %f",
                             self.default_brightness_percent)


    def _try_bl_cmd(self, arg_str):
        """Perform backlight command.

        Args:
          arg_str:  String of additional arguments to backlight command.

        Returns:
          String output of the backlight command.

        Raises:
          error.TestFail: if 'cmd' returns non-zero exit status.
        """
        if not self._can_control_bl:
            return 0
        cmd = 'backlight_tool %s' % (arg_str)
        logging.debug("backlight_cmd: %s", cmd)
        try:
            return utils.system_output(cmd).rstrip()
        except error.CmdError:
            raise error.TestFail(cmd)


    def set_level(self, level):
        """Set backlight level to the given brightness.

        Args:
          level: integer of brightness to set
        """
        self._try_bl_cmd('--set_brightness=%d' % (level))


    def set_percent(self, percent):
        """Set backlight level to the given brightness percent.

        Args:
          percent: float between 0 and 100
        """
        self._try_bl_cmd('--set_brightness_percent=%f' % (percent))


    def set_resume_level(self, level):
        """Set backlight level on resume to the given brightness.

        Args:
          level: integer of brightness to set
        """
        self._try_bl_cmd('--set_resume_brightness=%d' % (level))


    def set_resume_percent(self, percent):
        """Set backlight level on resume to the given brightness percent.

        Args:
          percent: float between 0 and 100
        """
        self._try_bl_cmd('--set_resume_brightness_percent=%f' % (percent))


    def set_default(self):
        """Set backlight to CrOS default.
        """
        self.set_percent(self.default_brightness_percent)


    def get_level(self):
        """Get backlight level currently.

        Returns integer of current backlight level or zero if no backlight
        exists.
        """
        return int(self._try_bl_cmd('--get_brightness'))


    def get_max_level(self):
        """Get maximum backight level.

        Returns integer of maximum backlight level or zero if no backlight
        exists.
        """
        return int(self._try_bl_cmd('--get_max_brightness'))


    def get_percent(self):
        """Get backlight percent currently.

        Returns float of current backlight percent or zero if no backlight
        exists
        """
        return float(self._try_bl_cmd('--get_brightness_percent'))


    def restore(self):
        """Restore backlight to initial level when instance created."""
        self.set_level(self._init_level)


class KbdBacklightException(Exception):
    """Class for KbdBacklight exceptions."""


class KbdBacklight(object):
    """Class for control of keyboard backlight.

    Example code:
        kblight = power_utils.KbdBacklight()
        kblight.set(10)
        print "kblight % is %.f" % kblight.get()

    Public methods:
        set: Sets the keyboard backlight to a percent.
        get: Get current keyboard backlight percentage.

    Private functions:
        _get_max: Retrieve maximum integer setting of keyboard backlight

    Private attributes:
        _path: filepath to keyboard backlight controls in sysfs
        _max: cached value of 'max_brightness' integer

    TODO(tbroch): deprecate direct sysfs access if/when these controls are
    integrated into a userland tool such as backlight_tool in power manager.
    """
    DEFAULT_PATH = "/sys/class/leds/chromeos::kbd_backlight"

    def __init__(self, path=DEFAULT_PATH):
        if not os.path.exists(path):
            raise KbdBacklightException('Unable to find path "%s"' % path)
        self._path = path
        self._max = None


    def _get_max(self):
        """Get maximum absolute value of keyboard brightness.

        Returns:
            integer, maximum value of keyboard brightness
        """
        if self._max is None:
            self._max = int(utils.read_one_line(os.path.join(self._path,
                                                             'max_brightness')))
        return self._max


    def get(self):
        """Get current keyboard brightness setting.

        Returns:
            float, percentage of keyboard brightness.
        """
        current = int(utils.read_one_line(os.path.join(self._path,
                                                       'brightness')))
        return (current * 100 ) / self._get_max()


    def set(self, percent):
        """Set keyboard backlight percent.

        Args:
        @param percent: percent to set keyboard backlight to.
        """
        value = int((percent * self._get_max()) / 100)
        cmd = "echo %d > %s" % (value, os.path.join(self._path, 'brightness'))
        utils.system(cmd)


class BacklightController(object):
    """Class to simulate control of backlight via keyboard or Chrome UI.

    Public methods:
      increase_brightness: Increase backlight by one adjustment step.
      decrease_brightness: Decrease backlight by one adjustment step.
      set_brightness_to_max: Increase backlight to max by calling
          increase_brightness()
      set_brightness_to_min: Decrease backlight to min or zero by calling
          decrease_brightness()

    Private attributes:
      _max_num_steps: maximum number of backlight adjustment steps between 0 and
                      max brightness.
    """

    def __init__(self):
        self._max_num_steps = 16


    def decrease_brightness(self, allow_off=False):
        """
        Decrease brightness by one step, as if the user pressed the brightness
        down key or button.

        Arguments
        @param allow_off: Boolean flag indicating whether the brightness can be
                     reduced to zero.
                     Set to true to simulate brightness down key.
                     set to false to simulate Chrome UI brightness down button.
        """
        call_powerd_dbus_method('DecreaseScreenBrightness',
                                'boolean:%s' % \
                                    ('true' if allow_off else 'false'))


    def increase_brightness(self):
        """
        Increase brightness by one step, as if the user pressed the brightness
        up key or button.
        """
        call_powerd_dbus_method('IncreaseScreenBrightness')


    def set_brightness_to_max(self):
        """
        Increases the brightness using powerd until the brightness reaches the
        maximum value. Returns when it reaches the maximum number of brightness
        adjustments
        """
        num_steps_taken = 0
        while num_steps_taken < self._max_num_steps:
            self.increase_brightness()
            num_steps_taken += 1


    def set_brightness_to_min(self, allow_off=False):
        """
        Decreases the brightness using powerd until the brightness reaches the
        minimum value (zero or the minimum nonzero value). Returns when it
        reaches the maximum number of brightness adjustments.

        Arguments
        @param allow_off: Boolean flag indicating whether the brightness can be
                     reduced to zero.
                     Set to true to simulate brightness down key.
                     set to false to simulate Chrome UI brightness down button.
        """
        num_steps_taken = 0
        while num_steps_taken < self._max_num_steps:
            self.decrease_brightness(allow_off)
            num_steps_taken += 1


class DisplayException(Exception):
    """Class for Display exceptions."""


def set_display_power(power_val):
    """Function to control screens via Chrome.

    Possible arguments:
      DISPLAY_POWER_ALL_ON,
      DISPLAY_POWER_ALL_OFF,
      DISPLAY_POWER_INTERNAL_OFF_EXTERNAL_ON,
      DISPLAY_POWER_INTERNAL_ON_EXTENRAL_OFF
    """
    if (not isinstance(power_val, int)
            or power_val < DISPLAY_POWER_ALL_ON
            or power_val >= DISPLAY_POWER_MAX):
        raise DisplayException('Invalid display power setting: %d' % power_val)
    call_chrome_dbus_method('SetDisplayPower', 'int32:%d' % power_val)


class PowerPrefChanger(object):
    """
    Class to temporarily change powerd prefs. Construct with a dict of
    pref_name/value pairs (e.g. {'disable_idle_suspend':0}). Destructor (or
    reboot) will restore old prefs automatically."""

    _PREFDIR = '/var/lib/power_manager'
    _TEMPDIR = '/tmp/autotest_powerd_prefs'

    def __init__(self, prefs):
        shutil.copytree(self._PREFDIR, self._TEMPDIR)
        for name, value in prefs.iteritems():
            utils.write_one_line('%s/%s' % (self._TEMPDIR, name), value)
        utils.system('mount --bind %s %s' % (self._TEMPDIR, self._PREFDIR))
        utils.restart_job('powerd')


    def finalize(self):
        """finalize"""
        if os.path.exists(self._TEMPDIR):
            utils.system('umount %s' % self._PREFDIR, ignore_status=True)
            shutil.rmtree(self._TEMPDIR)
            utils.restart_job('powerd')


    def __del__(self):
        self.finalize()


class Registers(object):
    """Class to examine PCI and MSR registers."""

    def __init__(self):
        self._cpu_id = 0
        self._rdmsr_cmd = 'iotools rdmsr'
        self._mmio_read32_cmd = 'iotools mmio_read32'
        self._rcba = 0xfed1c000

        self._pci_read32_cmd = 'iotools pci_read32'
        self._mch_bar = None
        self._dmi_bar = None

    def _init_mch_bar(self):
        if self._mch_bar != None:
            return
        # MCHBAR is at offset 0x48 of B/D/F 0/0/0
        cmd = '%s 0 0 0 0x48' % (self._pci_read32_cmd)
        self._mch_bar = int(utils.system_output(cmd), 16) & 0xfffffffe
        logging.debug('MCH BAR is %s', hex(self._mch_bar))

    def _init_dmi_bar(self):
        if self._dmi_bar != None:
            return
        # DMIBAR is at offset 0x68 of B/D/F 0/0/0
        cmd = '%s 0 0 0 0x68' % (self._pci_read32_cmd)
        self._dmi_bar = int(utils.system_output(cmd), 16) & 0xfffffffe
        logging.debug('DMI BAR is %s', hex(self._dmi_bar))

    def _read_msr(self, register):
        cmd = '%s %d %s' % (self._rdmsr_cmd, self._cpu_id, register)
        return int(utils.system_output(cmd), 16)

    def _read_mmio_read32(self, address):
        cmd = '%s 0x%x' % (self._mmio_read32_cmd, address)
        return int(utils.system_output(cmd), 16)

    def _read_dmi_bar(self, offset):
        self._init_dmi_bar()
        return self._read_mmio_read32(self._dmi_bar + int(offset, 16))

    def _read_mch_bar(self, offset):
        self._init_mch_bar()
        return self._read_mmio_read32(self._mch_bar + int(offset, 16))

    def _read_rcba(self, offset):
        return self._read_mmio_read32(self._rcba + int(offset, 16))

    def _shift_mask_match(self, reg_name, value, match):
        expr = match[1]
        bits = match[0].split(':')
        operator = match[2] if len(match) == 3 else '=='
        hi_bit = int(bits[0])
        if len(bits) == 2:
            lo_bit = int(bits[1])
        else:
            lo_bit = int(bits[0])

        value >>= lo_bit
        mask = (1 << (hi_bit - lo_bit + 1)) - 1
        value &= mask

        good = eval("%d %s %d" % (value, operator, expr))
        if not good:
            logging.error('FAILED: %s bits: %s value: %s mask: %s expr: %s ' +
                          'operator: %s', reg_name, bits, hex(value), mask,
                          expr, operator)
        return good

    def _verify_registers(self, reg_name, read_fn, match_list):
        errors = 0
        for k, v in match_list.iteritems():
            r = read_fn(k)
            for item in v:
                good = self._shift_mask_match(reg_name, r, item)
                if not good:
                    errors += 1
                    logging.error('Error(%d), %s: reg = %s val = %s match = %s',
                                  errors, reg_name, k, hex(r), v)
                else:
                    logging.debug('ok, %s: reg = %s val = %s match = %s',
                                  reg_name, k, hex(r), v)
        return errors

    def verify_msr(self, match_list):
        """
        Verify MSR

        @param match_list: match list
        """
        errors = 0
        for cpu_id in xrange(0, max(utils.count_cpus(), 1)):
            self._cpu_id = cpu_id
            errors += self._verify_registers('msr', self._read_msr, match_list)
        return errors

    def verify_dmi(self, match_list):
        """
        Verify DMI

        @param match_list: match list
        """
        return self._verify_registers('dmi', self._read_dmi_bar, match_list)

    def verify_mch(self, match_list):
        """
        Verify MCH

        @param match_list: match list
        """
        return self._verify_registers('mch', self._read_mch_bar, match_list)

    def verify_rcba(self, match_list):
        """
        Verify RCBA

        @param match_list: match list
        """
        return self._verify_registers('rcba', self._read_rcba, match_list)


class USBDevicePower(object):
    """Class for USB device related power information.

    Public Methods:
        autosuspend: Return boolean whether USB autosuspend is enabled or False
                     if not or unable to determine

    Public attributes:
        vid: string of USB Vendor ID
        pid: string of USB Product ID
        whitelisted: Boolean if USB device is whitelisted for USB auto-suspend

    Private attributes:
       path: string to path of the USB devices in sysfs ( /sys/bus/usb/... )

    TODO(tbroch): consider converting to use of pyusb although not clear its
    beneficial if it doesn't parse power/control
    """
    def __init__(self, vid, pid, whitelisted, path):
        self.vid = vid
        self.pid = pid
        self.whitelisted = whitelisted
        self._path = path


    def autosuspend(self):
        """Determine current value of USB autosuspend for device."""
        control_file = os.path.join(self._path, 'control')
        if not os.path.exists(control_file):
            logging.info('USB: power control file not found for %s', dir)
            return False

        out = utils.read_one_line(control_file)
        logging.debug('USB: control set to %s for %s', out, control_file)
        return (out == 'auto')


class USBPower(object):
    """Class to expose USB related power functionality.

    Initially that includes the policy around USB auto-suspend and our
    whitelisting of devices that are internal to CrOS system.

    Example code:
       usbdev_power = power_utils.USBPower()
       for device in usbdev_power.devices
           if device.is_whitelisted()
               ...

    Public attributes:
        devices: list of USBDevicePower instances

    Private functions:
        _is_whitelisted: Returns Boolean if USB device is whitelisted for USB
                         auto-suspend
        _load_whitelist: Reads whitelist and stores int _whitelist attribute

    Private attributes:
        _wlist_file: path to laptop-mode-tools (LMT) USB autosuspend
                         conf file.
        _wlist_vname: string name of LMT USB autosuspend whitelist
                          variable
        _whitelisted: list of USB device vid:pid that are whitelisted.
                        May be regular expressions.  See LMT for details.
    """
    def __init__(self):
        self._wlist_file = \
            '/etc/laptop-mode/conf.d/board-specific/usb-autosuspend.conf'
        self._wlist_vname = '$AUTOSUSPEND_USBID_WHITELIST'
        self._whitelisted = None
        self.devices = []


    def _load_whitelist(self):
        """Load USB device whitelist for enabling USB autosuspend

        CrOS whitelists only internal USB devices to enter USB auto-suspend mode
        via laptop-mode tools.
        """
        cmd = "source %s && echo %s" % (self._wlist_file,
                                        self._wlist_vname)
        out = utils.system_output(cmd, ignore_status=True)
        logging.debug('USB whitelist = %s', out)
        self._whitelisted = out.split()


    def _is_whitelisted(self, vid, pid):
        """Check to see if USB device vid:pid is whitelisted.

        Args:
          vid: string of USB vendor ID
          pid: string of USB product ID

        Returns:
          True if vid:pid in whitelist file else False
        """
        if self._whitelisted is None:
            self._load_whitelist()

        match_str = "%s:%s" % (vid, pid)
        for re_str in self._whitelisted:
            if re.match(re_str, match_str):
                return True
        return False


    def query_devices(self):
        """."""
        dirs_path = '/sys/bus/usb/devices/*/power'
        dirs = glob.glob(dirs_path)
        if not dirs:
            logging.info('USB power path not found')
            return 1

        for dirpath in dirs:
            vid_path = os.path.join(dirpath, '..', 'idVendor')
            pid_path = os.path.join(dirpath, '..', 'idProduct')
            if not os.path.exists(vid_path):
                logging.debug("No vid for USB @ %s", vid_path)
                continue
            vid = utils.read_one_line(vid_path)
            pid = utils.read_one_line(pid_path)
            whitelisted = self._is_whitelisted(vid, pid)
            self.devices.append(USBDevicePower(vid, pid, whitelisted, dirpath))
