# 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 collections, ctypes, fcntl, glob, logging, math, numpy, os, re, struct
import threading, time

from autotest_lib.client.bin import utils
from autotest_lib.client.common_lib import error, enum
from autotest_lib.client.cros import kernel_trace

BatteryDataReportType = enum.Enum('CHARGE', 'ENERGY')

# battery data reported at 1e6 scale
BATTERY_DATA_SCALE = 1e6
# number of times to retry reading the battery in the case of bad data
BATTERY_RETRY_COUNT = 3

class DevStat(object):
    """
    Device power status. This class implements generic status initialization
    and parsing routines.
    """

    def __init__(self, fields, path=None):
        self.fields = fields
        self.path = path


    def reset_fields(self):
        """
        Reset all class fields to None to mark their status as unknown.
        """
        for field in self.fields.iterkeys():
            setattr(self, field, None)


    def read_val(self,  file_name, field_type):
        try:
            path = file_name
            if not file_name.startswith('/'):
                path = os.path.join(self.path, file_name)
            f = open(path, 'r')
            out = f.readline()
            val = field_type(out)
            return val

        except:
            return field_type(0)


    def read_all_vals(self):
        for field, prop in self.fields.iteritems():
            if prop[0]:
                val = self.read_val(prop[0], prop[1])
                setattr(self, field, val)


class ThermalStatACPI(DevStat):
    """
    ACPI-based thermal status.

    Fields:
    (All temperatures are in millidegrees Celsius.)

    str   enabled:            Whether thermal zone is enabled
    int   temp:               Current temperature
    str   type:               Thermal zone type
    int   num_trip_points:    Number of thermal trip points that activate
                                cooling devices
    int   num_points_tripped: Temperature is above this many trip points
    str   trip_point_N_type:  Trip point #N's type
    int   trip_point_N_temp:  Trip point #N's temperature value
    int   cdevX_trip_point:   Trip point o cooling device #X (index)
    """

    MAX_TRIP_POINTS = 20

    thermal_fields = {
        'enabled':              ['enabled', str],
        'temp':                 ['temp', int],
        'type':                 ['type', str],
        'num_points_tripped':   ['', '']
        }
    path = '/sys/class/thermal/thermal_zone*'

    def __init__(self, path=None):
        # Browse the thermal folder for trip point fields.
        self.num_trip_points = 0

        thermal_fields = glob.glob(path + '/*')
        for file in thermal_fields:
            field = file[len(path + '/'):]
            if field.find('trip_point') != -1:
                if field.find('temp'):
                    field_type = int
                else:
                    field_type = str
                self.thermal_fields[field] = [field, field_type]

                # Count the number of trip points.
                if field.find('_type') != -1:
                    self.num_trip_points += 1

        super(ThermalStatACPI, self).__init__(self.thermal_fields, path)
        self.update()

    def update(self):
        if not os.path.exists(self.path):
            return

        self.read_all_vals()
        self.num_points_tripped = 0

        for field in self.thermal_fields:
            if field.find('trip_point_') != -1 and field.find('_temp') != -1 \
                    and self.temp > self.read_val(field, int):
                self.num_points_tripped += 1
                logging.info('Temperature trip point #' + \
                            field[len('trip_point_'):field.rfind('_temp')] + \
                            ' tripped.')


class ThermalStatHwmon(DevStat):
    """
    hwmon-based thermal status.

    Fields:
    int   <tname>_temp<num>_input: Current temperature in millidegrees Celsius
      where:
          <tname> : name of hwmon device in sysfs
          <num>   : number of temp as some hwmon devices have multiple

    """
    path = '/sys/class/hwmon'

    thermal_fields = {}
    def __init__(self, rootpath=None):
        if not rootpath:
            rootpath = self.path
        for subpath1 in glob.glob('%s/hwmon*' % rootpath):
            for subpath2 in ['','device/']:
                gpaths = glob.glob("%s/%stemp*_input" % (subpath1, subpath2))
                for gpath in gpaths:
                    bname = os.path.basename(gpath)
                    field_path = os.path.join(subpath1, subpath2, bname)

                    tname_path = os.path.join(os.path.dirname(gpath), "name")
                    tname = utils.read_one_line(tname_path)

                    field_key = "%s_%s" % (tname, bname)
                    self.thermal_fields[field_key] = [field_path, int]

        super(ThermalStatHwmon, self).__init__(self.thermal_fields, rootpath)
        self.update()

    def update(self):
        if not os.path.exists(self.path):
            return

        self.read_all_vals()

    def read_val(self,  file_name, field_type):
        try:
            path = os.path.join(self.path, file_name)
            f = open(path, 'r')
            out = f.readline()
            return field_type(out)
        except:
            return field_type(0)


class ThermalStat(object):
    """helper class to instantiate various thermal devices."""
    def __init__(self):
        self._thermals = []
        self.min_temp = 999999999
        self.max_temp = -999999999

        thermal_stat_types = [(ThermalStatHwmon.path, ThermalStatHwmon),
                              (ThermalStatACPI.path, ThermalStatACPI)]
        for thermal_glob_path, thermal_type in thermal_stat_types:
            try:
                thermal_path = glob.glob(thermal_glob_path)[0]
                logging.debug('Using %s for thermal info.' % thermal_path)
                self._thermals.append(thermal_type(thermal_path))
            except:
                logging.debug('Could not find thermal path %s, skipping.' %
                              thermal_glob_path)


    def get_temps(self):
        """Get temperature readings.

        Returns:
            string of temperature readings.
        """
        temp_str = ''
        for thermal in self._thermals:
            thermal.update()
            for kname in thermal.fields:
                if kname is 'temp' or kname.endswith('_input'):
                    val = getattr(thermal, kname)
                    temp_str += '%s:%d ' % (kname, val)
                    if val > self.max_temp:
                        self.max_temp = val
                    if val < self.min_temp:
                        self.min_temp = val


        return temp_str


class BatteryStat(DevStat):
    """
    Battery status.

    Fields:

    float charge_full:        Last full capacity reached [Ah]
    float charge_full_design: Full capacity by design [Ah]
    float charge_now:         Remaining charge [Ah]
    float current_now:        Battery discharge rate [A]
    float energy:             Current battery charge [Wh]
    float energy_full:        Last full capacity reached [Wh]
    float energy_full_design: Full capacity by design [Wh]
    float energy_rate:        Battery discharge rate [W]
    float power_now:          Battery discharge rate [W]
    float remaining_time:     Remaining discharging time [h]
    float voltage_min_design: Minimum voltage by design [V]
    float voltage_max_design: Maximum voltage by design [V]
    float voltage_now:        Voltage now [V]
    """

    battery_fields = {
        'status':               ['status', str],
        'charge_full':          ['charge_full', float],
        'charge_full_design':   ['charge_full_design', float],
        'charge_now':           ['charge_now', float],
        'current_now':          ['current_now', float],
        'voltage_min_design':   ['voltage_min_design', float],
        'voltage_max_design':   ['voltage_max_design', float],
        'voltage_now':          ['voltage_now', float],
        'energy':               ['energy_now', float],
        'energy_full':          ['energy_full', float],
        'energy_full_design':   ['energy_full_design', float],
        'power_now':            ['power_now', float],
        'energy_rate':          ['', ''],
        'remaining_time':       ['', '']
        }

    def __init__(self, path=None):
        super(BatteryStat, self).__init__(self.battery_fields, path)
        self.update()


    def update(self):
        for _ in xrange(BATTERY_RETRY_COUNT):
            try:
                self._read_battery()
                return
            except error.TestError as e:
                logging.warn(e)
                continue
        raise error.TestError('Failed to read battery state')


    def _read_battery(self):
        self.read_all_vals()

        if self.charge_full == 0 and self.energy_full != 0:
            battery_type = BatteryDataReportType.ENERGY
        else:
            battery_type = BatteryDataReportType.CHARGE

        if self.voltage_min_design != 0:
            voltage_nominal = self.voltage_min_design
        else:
            voltage_nominal = self.voltage_now

        if voltage_nominal == 0:
            raise error.TestError('Failed to determine battery voltage')

        # Since charge data is present, calculate parameters based upon
        # reported charge data.
        if battery_type == BatteryDataReportType.CHARGE:
            self.charge_full = self.charge_full / BATTERY_DATA_SCALE
            self.charge_full_design = self.charge_full_design / \
                                      BATTERY_DATA_SCALE
            self.charge_now = self.charge_now / BATTERY_DATA_SCALE

            self.current_now = math.fabs(self.current_now) / \
                               BATTERY_DATA_SCALE

            self.energy =  voltage_nominal * \
                           self.charge_now / \
                           BATTERY_DATA_SCALE
            self.energy_full = voltage_nominal * \
                               self.charge_full / \
                               BATTERY_DATA_SCALE
            self.energy_full_design = voltage_nominal * \
                                      self.charge_full_design / \
                                      BATTERY_DATA_SCALE

        # Charge data not present, so calculate parameters based upon
        # reported energy data.
        elif battery_type == BatteryDataReportType.ENERGY:
            self.charge_full = self.energy_full / voltage_nominal
            self.charge_full_design = self.energy_full_design / \
                                      voltage_nominal
            self.charge_now = self.energy / voltage_nominal

            # TODO(shawnn): check if power_now can really be reported
            # as negative, in the same way current_now can
            self.current_now = math.fabs(self.power_now) / \
                               voltage_nominal

            self.energy = self.energy / BATTERY_DATA_SCALE
            self.energy_full = self.energy_full / BATTERY_DATA_SCALE
            self.energy_full_design = self.energy_full_design / \
                                      BATTERY_DATA_SCALE

        self.voltage_min_design = self.voltage_min_design / \
                                  BATTERY_DATA_SCALE
        self.voltage_max_design = self.voltage_max_design / \
                                  BATTERY_DATA_SCALE
        self.voltage_now = self.voltage_now / \
                           BATTERY_DATA_SCALE
        voltage_nominal = voltage_nominal / \
                          BATTERY_DATA_SCALE

        if self.charge_full > (self.charge_full_design * 1.5):
            raise error.TestError('Unreasonable charge_full value')
        if self.charge_now > (self.charge_full_design * 1.5):
            raise error.TestError('Unreasonable charge_now value')

        self.energy_rate =  self.voltage_now * self.current_now

        self.remaining_time = 0
        if self.current_now and self.energy_rate:
            self.remaining_time =  self.energy / self.energy_rate


class LineStatDummy(object):
    """
    Dummy line stat for devices which don't provide power_supply related sysfs
    interface.
    """
    def __init__(self):
        self.online = True


    def update(self):
        pass

class LineStat(DevStat):
    """
    Power line status.

    Fields:

    bool online:              Line power online
    """

    linepower_fields = {
        'is_online':             ['online', int]
        }


    def __init__(self, path=None):
        super(LineStat, self).__init__(self.linepower_fields, path)
        logging.debug("line path: %s", path)
        self.update()


    def update(self):
        self.read_all_vals()
        self.online = self.is_online == 1


class SysStat(object):
    """
    System power status for a given host.

    Fields:

    battery:   A list of BatteryStat objects.
    linepower: A list of LineStat objects.
    """
    psu_types = ['Mains', 'USB', 'USB_ACA', 'USB_C', 'USB_CDP', 'USB_DCP',
                 'USB_PD', 'USB_PD_DRP', 'Unknown']

    def __init__(self):
        power_supply_path = '/sys/class/power_supply/*'
        self.battery = None
        self.linepower = []
        self.thermal = None
        self.battery_path = None
        self.linepower_path = []

        power_supplies = glob.glob(power_supply_path)
        for path in power_supplies:
            type_path = os.path.join(path,'type')
            if not os.path.exists(type_path):
                continue
            power_type = utils.read_one_line(type_path)
            if power_type == 'Battery':
                self.battery_path = path
            elif power_type in self.psu_types:
                self.linepower_path.append(path)

        if not self.battery_path or not self.linepower_path:
            logging.warning("System does not provide power sysfs interface")

        self.thermal = ThermalStat()


    def refresh(self):
        """
        Initialize device power status objects.
        """
        self.linepower = []

        if self.battery_path:
            self.battery = [ BatteryStat(self.battery_path) ]

        for path in self.linepower_path:
            self.linepower.append(LineStat(path))
        if not self.linepower:
            self.linepower = [ LineStatDummy() ]

        temp_str = self.thermal.get_temps()
        if temp_str:
            logging.info('Temperature reading: ' + temp_str)
        else:
            logging.error('Could not read temperature, skipping.')


    def on_ac(self):
        """
        Returns true if device is currently running from AC power.
        """
        on_ac = False
        for linepower in self.linepower:
            on_ac |= linepower.online

        # Butterfly can incorrectly report AC online for some time after
        # unplug. Check battery discharge state to confirm.
        if utils.get_board() == 'butterfly':
            on_ac &= (not self.battery_discharging())
        return on_ac

    def battery_discharging(self):
        """
        Returns true if battery is currently discharging.
        """
        return(self.battery[0].status.rstrip() == 'Discharging')

    def percent_current_charge(self):
        return self.battery[0].charge_now * 100 / \
               self.battery[0].charge_full_design


    def assert_battery_state(self, percent_initial_charge_min):
        """Check initial power configuration state is battery.

        Args:
          percent_initial_charge_min: float between 0 -> 1.00 of
            percentage of battery that must be remaining.
            None|0|False means check not performed.

        Raises:
          TestError: if one of battery assertions fails
        """
        if self.on_ac():
            raise error.TestError(
                'Running on AC power. Please remove AC power cable.')

        percent_initial_charge = self.percent_current_charge()

        if percent_initial_charge_min and percent_initial_charge < \
                                          percent_initial_charge_min:
            raise error.TestError('Initial charge (%f) less than min (%f)'
                      % (percent_initial_charge, percent_initial_charge_min))


def get_status():
    """
    Return a new power status object (SysStat). A new power status snapshot
    for a given host can be obtained by either calling this routine again and
    constructing a new SysStat object, or by using the refresh method of the
    SysStat object.
    """
    status = SysStat()
    status.refresh()
    return status


class AbstractStats(object):
    """
    Common superclass for measurements of percentages per state over time.

    Public Attributes:
        incremental:  If False, stats returned are from a single
        _read_stats.  Otherwise, stats are from the difference between
        the current and last refresh.
    """

    @staticmethod
    def to_percent(stats):
        """
        Turns a dict with absolute time values into a dict with percentages.
        """
        total = sum(stats.itervalues())
        if total == 0:
            return {}
        return dict((k, v * 100.0 / total) for (k, v) in stats.iteritems())


    @staticmethod
    def do_diff(new, old):
        """
        Returns a dict with value deltas from two dicts with matching keys.
        """
        return dict((k, new[k] - old.get(k, 0)) for k in new.iterkeys())


    @staticmethod
    def format_results_percent(results, name, percent_stats):
        """
        Formats autotest result keys to format:
          percent_<name>_<key>_time
        """
        for key in percent_stats:
            results['percent_%s_%s_time' % (name, key)] = percent_stats[key]


    @staticmethod
    def format_results_wavg(results, name, wavg):
        """
        Add an autotest result keys to format: wavg_<name>
        """
        if wavg is not None:
            results['wavg_%s' % (name)] = wavg


    def __init__(self, name=None, incremental=True):
        if not name:
            error.TestFail("Need to name AbstractStats instance please.")
        self.name = name
        self.incremental = incremental
        self._stats = self._read_stats()


    def refresh(self):
        """
        Returns dict mapping state names to percentage of time spent in them.
        """
        raw_stats = result = self._read_stats()
        if self.incremental:
            result = self.do_diff(result, self._stats)
        self._stats = raw_stats
        return self.to_percent(result)


    def _automatic_weighted_average(self):
        """
        Turns a dict with absolute times (or percentages) into a weighted
        average value.
        """
        total = sum(self._stats.itervalues())
        if total == 0:
            return None

        return sum((float(k)*v) / total for (k, v) in self._stats.iteritems())


    def _supports_automatic_weighted_average(self):
        """
        Override!

        Returns True if stats collected can be automatically converted from
        percent distribution to weighted average. False otherwise.
        """
        return False


    def weighted_average(self):
        """
        Return weighted average calculated using the automated average method
        (if supported) or using a custom method defined by the stat.
        """
        if self._supports_automatic_weighted_average():
            return self._automatic_weighted_average()

        return self._weighted_avg_fn()


    def _weighted_avg_fn(self):
        """
        Override! Custom weighted average function.

        Returns weighted average as a single floating point value.
        """
        return None


    def _read_stats(self):
        """
        Override! Reads the raw data values that shall be measured into a dict.
        """
        raise NotImplementedError('Override _read_stats in the subclass!')


class CPUFreqStats(AbstractStats):
    """
    CPU Frequency statistics
    """

    def __init__(self, start_cpu=-1, end_cpu=-1):
        cpufreq_stats_path = '/sys/devices/system/cpu/cpu*/cpufreq/stats/' + \
                             'time_in_state'
        intel_pstate_stats_path = '/sys/devices/system/cpu/intel_pstate/' + \
                             'aperf_mperf'
        self._file_paths = glob.glob(cpufreq_stats_path)
        num_cpus = len(self._file_paths)
        self._intel_pstate_file_paths = glob.glob(intel_pstate_stats_path)
        self._running_intel_pstate = False
        self._initial_perf = None
        self._current_perf = None
        self._max_freq = 0
        name = 'cpufreq'
        if not self._file_paths:
            logging.debug('time_in_state file not found')
            if self._intel_pstate_file_paths:
                logging.debug('intel_pstate frequency stats file found')
                self._running_intel_pstate = True
        else:
            if (start_cpu >= 0 and end_cpu >= 0
                    and not (start_cpu == 0 and end_cpu == num_cpus - 1)):
                self._file_paths = self._file_paths[start_cpu : end_cpu]
                name += '_' + str(start_cpu) + '_' + str(end_cpu)

        super(CPUFreqStats, self).__init__(name=name)


    def _read_stats(self):
        if self._running_intel_pstate:
            aperf = 0
            mperf = 0

            for path in self._intel_pstate_file_paths:
                if not os.path.exists(path):
                    logging.debug('%s is not found', path)
                    continue
                data = utils.read_file(path)
                for line in data.splitlines():
                    pair = line.split()
                    # max_freq is supposed to be the same for all CPUs
                    # and remain constant throughout.
                    # So, we set the entry only once
                    if not self._max_freq:
                        self._max_freq = int(pair[0])
                    aperf += int(pair[1])
                    mperf += int(pair[2])

            if not self._initial_perf:
                self._initial_perf = (aperf, mperf)

            self._current_perf = (aperf, mperf)

        stats = {}
        for path in self._file_paths:
            if not os.path.exists(path):
                logging.debug('%s is not found', path)
                continue

            data = utils.read_file(path)
            for line in data.splitlines():
                pair = line.split()
                freq = int(pair[0])
                timeunits = int(pair[1])
                if freq in stats:
                    stats[freq] += timeunits
                else:
                    stats[freq] = timeunits
        return stats


    def _supports_automatic_weighted_average(self):
        return not self._running_intel_pstate


    def _weighted_avg_fn(self):
        if not self._running_intel_pstate:
            return None

        if self._current_perf[1] != self._initial_perf[1]:
            # Avg freq = max_freq * aperf_delta / mperf_delta
            return self._max_freq * \
                float(self._current_perf[0] - self._initial_perf[0]) / \
                (self._current_perf[1] - self._initial_perf[1])
        return 1.0


class CPUIdleStats(AbstractStats):
    """
    CPU Idle statistics (refresh() will not work with incremental=False!)
    """
    # TODO (snanda): Handle changes in number of c-states due to events such
    # as ac <-> battery transitions.
    # TODO (snanda): Handle non-S0 states. Time spent in suspend states is
    # currently not factored out.
    def __init__(self, start_cpu=-1, end_cpu=-1):
        cpuidle_path = '/sys/devices/system/cpu/cpu*/cpuidle'
        self._cpus = glob.glob(cpuidle_path)
        num_cpus = len(self._cpus)
        name = 'cpuidle'
        if (start_cpu >= 0 and end_cpu >= 0
                and not (start_cpu == 0 and end_cpu == num_cpus - 1)):
            self._cpus = self._cpus[start_cpu : end_cpu]
            name = name + '_' + str(start_cpu) + '_' + str(end_cpu)
        super(CPUIdleStats, self).__init__(name=name)


    def _read_stats(self):
        cpuidle_stats = collections.defaultdict(int)
        epoch_usecs = int(time.time() * 1000 * 1000)
        for cpu in self._cpus:
            state_path = os.path.join(cpu, 'state*')
            states = glob.glob(state_path)
            cpuidle_stats['C0'] += epoch_usecs

            for state in states:
                name = utils.read_one_line(os.path.join(state, 'name'))
                latency = utils.read_one_line(os.path.join(state, 'latency'))

                if not int(latency) and name == 'POLL':
                    # C0 state. Kernel stats aren't right, so calculate by
                    # subtracting all other states from total time (using epoch
                    # timer since we calculate differences in the end anyway).
                    # NOTE: Only x86 lists C0 under cpuidle, ARM does not.
                    continue

                usecs = int(utils.read_one_line(os.path.join(state, 'time')))
                cpuidle_stats['C0'] -= usecs

                if name == '<null>':
                    # Kernel race condition that can happen while a new C-state
                    # gets added (e.g. AC->battery). Don't know the 'name' of
                    # the state yet, but its 'time' would be 0 anyway.
                    logging.warning('Read name: <null>, time: %d from %s'
                        % (usecs, state) + '... skipping.')
                    continue

                cpuidle_stats[name] += usecs

        return cpuidle_stats


class CPUPackageStats(AbstractStats):
    """
    Package C-state residency statistics for modern Intel CPUs.
    """

    ATOM         =              {'C2': 0x3F8, 'C4': 0x3F9, 'C6': 0x3FA}
    NEHALEM      =              {'C3': 0x3F8, 'C6': 0x3F9, 'C7': 0x3FA}
    SANDY_BRIDGE = {'C2': 0x60D, 'C3': 0x3F8, 'C6': 0x3F9, 'C7': 0x3FA}
    HASWELL      = {'C2': 0x60D, 'C3': 0x3F8, 'C6': 0x3F9, 'C7': 0x3FA,
                                 'C8': 0x630, 'C9': 0x631,'C10': 0x632}

    def __init__(self):
        def _get_platform_states():
            """
            Helper to decide what set of microarchitecture-specific MSRs to use.

            Returns: dict that maps C-state name to MSR address, or None.
            """
            modalias = '/sys/devices/system/cpu/modalias'
            if not os.path.exists(modalias):
                return None

            values = utils.read_one_line(modalias).split(':')
            # values[2]: vendor, values[4]: family, values[6]: model (CPUID)
            if values[2] != '0000' or values[4] != '0006':
                return None

            return {
                # model groups pulled from Intel manual, volume 3 chapter 35
                '0027': self.ATOM,         # unreleased? (Next Generation Atom)
                '001A': self.NEHALEM,      # Bloomfield, Nehalem-EP (i7/Xeon)
                '001E': self.NEHALEM,      # Clarks-/Lynnfield, Jasper (i5/i7/X)
                '001F': self.NEHALEM,      # unreleased? (abandoned?)
                '0025': self.NEHALEM,      # Arran-/Clarksdale (i3/i5/i7/C/X)
                '002C': self.NEHALEM,      # Gulftown, Westmere-EP (i7/Xeon)
                '002E': self.NEHALEM,      # Nehalem-EX (Xeon)
                '002F': self.NEHALEM,      # Westmere-EX (Xeon)
                '002A': self.SANDY_BRIDGE, # SandyBridge (i3/i5/i7/C/X)
                '002D': self.SANDY_BRIDGE, # SandyBridge-E (i7)
                '003A': self.SANDY_BRIDGE, # IvyBridge (i3/i5/i7/X)
                '003C': self.HASWELL,      # Haswell (Core/Xeon)
                '003D': self.HASWELL,      # Broadwell (Core)
                '003E': self.SANDY_BRIDGE, # IvyBridge (Xeon)
                '003F': self.HASWELL,      # Haswell-E (Core/Xeon)
                '004F': self.HASWELL,      # Broadwell (Xeon)
                '0056': self.HASWELL,      # Broadwell (Xeon D)
                }.get(values[6], None)

        self._platform_states = _get_platform_states()
        super(CPUPackageStats, self).__init__(name='cpupkg')


    def _read_stats(self):
        packages = set()
        template = '/sys/devices/system/cpu/cpu%s/topology/physical_package_id'
        if not self._platform_states:
            return {}
        stats = dict((state, 0) for state in self._platform_states)
        stats['C0_C1'] = 0

        for cpu in os.listdir('/dev/cpu'):
            if not os.path.exists(template % cpu):
                continue
            package = utils.read_one_line(template % cpu)
            if package in packages:
                continue
            packages.add(package)

            stats['C0_C1'] += utils.rdmsr(0x10, cpu) # TSC
            for (state, msr) in self._platform_states.iteritems():
                ticks = utils.rdmsr(msr, cpu)
                stats[state] += ticks
                stats['C0_C1'] -= ticks

        return stats


class DevFreqStats(AbstractStats):
    """
    Devfreq device frequency stats.
    """

    _DIR = '/sys/class/devfreq'


    def __init__(self, f):
        """Constructs DevFreqStats Object that track frequency stats
        for the path of the given Devfreq device.

        The frequencies for devfreq devices are listed in Hz.

        Args:
            path: the path to the devfreq device

        Example:
            /sys/class/devfreq/dmc
        """
        self._path = os.path.join(self._DIR, f)
        if not os.path.exists(self._path):
            raise error.TestError('DevFreqStats: devfreq device does not exist')

        fname = os.path.join(self._path, 'available_frequencies')
        af = utils.read_one_line(fname).strip()
        self._available_freqs = sorted(af.split(), key=int)

        super(DevFreqStats, self).__init__(name=f)

    def _read_stats(self):
        stats = dict((freq, 0) for freq in self._available_freqs)
        fname = os.path.join(self._path, 'trans_stat')

        with open(fname) as fd:
            # The lines that contain the time in each frequency start on the 3rd
            # line, so skip the first 2 lines. The last line contains the number
            # of transitions, so skip that line too.
            # The time in each frequency is at the end of the line.
            freq_pattern = re.compile(r'\d+(?=:)')
            for line in fd.readlines()[2:-1]:
                freq = freq_pattern.search(line)
                if freq and freq.group() in self._available_freqs:
                    stats[freq.group()] = int(line.strip().split()[-1])

        return stats


class GPUFreqStats(AbstractStats):
    """GPU Frequency statistics class.

    TODO(tbroch): add stats for other GPUs
    """

    _MALI_DEV = '/sys/class/misc/mali0/device'
    _MALI_EVENTS = ['mali_dvfs:mali_dvfs_set_clock']
    _MALI_TRACE_CLK_RE = r'(\d+.\d+): mali_dvfs_set_clock: frequency=(\d+)\d{6}'

    _I915_ROOT = '/sys/kernel/debug/dri/0'
    _I915_EVENTS = ['i915:intel_gpu_freq_change']
    _I915_CLK = os.path.join(_I915_ROOT, 'i915_cur_delayinfo')
    _I915_TRACE_CLK_RE = r'(\d+.\d+): intel_gpu_freq_change: new_freq=(\d+)'
    _I915_CUR_FREQ_RE = r'CAGF:\s+(\d+)MHz'
    _I915_MIN_FREQ_RE = r'Lowest \(RPN\) frequency:\s+(\d+)MHz'
    _I915_MAX_FREQ_RE = r'Max non-overclocked \(RP0\) frequency:\s+(\d+)MHz'
    # TODO(dbasehore) parse this from debugfs if/when this value is added
    _I915_FREQ_STEP = 50

    _gpu_type = None


    def _get_mali_freqs(self):
        """Get mali clocks based on kernel version.

        For 3.8-3.18:
            # cat /sys/class/misc/mali0/device/clock
            100000000
            # cat /sys/class/misc/mali0/device/available_frequencies
            100000000
            160000000
            266000000
            350000000
            400000000
            450000000
            533000000
            533000000

        For 4.4+:
            Tracked in DevFreqStats

        Returns:
          cur_mhz: string of current GPU clock in mhz
        """
        cur_mhz = None
        fqs = []

        fname = os.path.join(self._MALI_DEV, 'clock')
        if os.path.exists(fname):
            cur_mhz = str(int(int(utils.read_one_line(fname).strip()) / 1e6))
            fname = os.path.join(self._MALI_DEV, 'available_frequencies')
            with open(fname) as fd:
                for ln in fd.readlines():
                    freq = int(int(ln.strip()) / 1e6)
                    fqs.append(str(freq))
                fqs.sort()

        self._freqs = fqs
        return cur_mhz


    def __init__(self, incremental=False):


        min_mhz = None
        max_mhz = None
        cur_mhz = None
        events = None
        self._freqs = []
        self._prev_sample = None
        self._trace = None

        if os.path.exists(self._MALI_DEV) and \
           not os.path.exists(os.path.join(self._MALI_DEV, "devfreq")):
            self._set_gpu_type('mali')
        elif os.path.exists(self._I915_CLK):
            self._set_gpu_type('i915')
        else:
            # We either don't know how to track GPU stats (yet) or the stats are
            # tracked in DevFreqStats.
            self._set_gpu_type(None)

        logging.debug("gpu_type is %s", self._gpu_type)

        if self._gpu_type is 'mali':
            events = self._MALI_EVENTS
            cur_mhz = self._get_mali_freqs()
            if self._freqs:
                min_mhz = self._freqs[0]
                max_mhz = self._freqs[-1]

        elif self._gpu_type is 'i915':
            events = self._I915_EVENTS
            with open(self._I915_CLK) as fd:
                for ln in fd.readlines():
                    logging.debug("ln = %s", ln)
                    result = re.findall(self._I915_CUR_FREQ_RE, ln)
                    if result:
                        cur_mhz = result[0]
                        continue
                    result = re.findall(self._I915_MIN_FREQ_RE, ln)
                    if result:
                        min_mhz = result[0]
                        continue
                    result = re.findall(self._I915_MAX_FREQ_RE, ln)
                    if result:
                        max_mhz = result[0]
                        continue
                if min_mhz and max_mhz:
                    for i in xrange(int(min_mhz), int(max_mhz) +
                                    self._I915_FREQ_STEP, self._I915_FREQ_STEP):
                        self._freqs.append(str(i))

        logging.debug("cur_mhz = %s, min_mhz = %s, max_mhz = %s", cur_mhz,
                      min_mhz, max_mhz)

        if cur_mhz and min_mhz and max_mhz:
            self._trace = kernel_trace.KernelTrace(events=events)

        # Not all platforms or kernel versions support tracing.
        if not self._trace or not self._trace.is_tracing():
            logging.warning("GPU frequency tracing not enabled.")
        else:
            self._prev_sample = (cur_mhz, self._trace.uptime_secs())
            logging.debug("Current GPU freq: %s", cur_mhz)
            logging.debug("All GPU freqs: %s", self._freqs)

        super(GPUFreqStats, self).__init__(name='gpu', incremental=incremental)


    @classmethod
    def _set_gpu_type(cls, gpu_type):
        cls._gpu_type = gpu_type


    def _read_stats(self):
        if self._gpu_type:
            return getattr(self, "_%s_read_stats" % self._gpu_type)()
        return {}


    def _trace_read_stats(self, regexp):
        """Read GPU stats from kernel trace outputs.

        Args:
            regexp: regular expression to match trace output for frequency

        Returns:
            Dict with key string in mhz and val float in seconds.
        """
        if not self._prev_sample:
            return {}

        stats = dict((k, 0.0) for k in self._freqs)
        results = self._trace.read(regexp=regexp)
        for (tstamp_str, freq) in results:
            tstamp = float(tstamp_str)

            # do not reparse lines in trace buffer
            if tstamp <= self._prev_sample[1]:
                continue
            delta = tstamp - self._prev_sample[1]
            logging.debug("freq:%s tstamp:%f - %f delta:%f",
                          self._prev_sample[0],
                          tstamp, self._prev_sample[1],
                          delta)
            stats[self._prev_sample[0]] += delta
            self._prev_sample = (freq, tstamp)

        # Do last record
        delta = self._trace.uptime_secs() - self._prev_sample[1]
        logging.debug("freq:%s tstamp:uptime - %f delta:%f",
                      self._prev_sample[0],
                      self._prev_sample[1], delta)
        stats[self._prev_sample[0]] += delta

        logging.debug("GPU freq percents:%s", stats)
        return stats


    def _mali_read_stats(self):
        """Read Mali GPU stats

        Frequencies are reported in Hz, so use a regex that drops the last 6
        digits.

        Output in trace looks like this:

            kworker/u:24-5220  [000] .... 81060.329232: mali_dvfs_set_clock: frequency=400
            kworker/u:24-5220  [000] .... 81061.830128: mali_dvfs_set_clock: frequency=350

        Returns:
            Dict with frequency in mhz as key and float in seconds for time
              spent at that frequency.
        """
        return self._trace_read_stats(self._MALI_TRACE_CLK_RE)


    def _i915_read_stats(self):
        """Read i915 GPU stats.

        Output looks like this (kernel >= 3.8):

          kworker/u:0-28247 [000] .... 259391.579610: intel_gpu_freq_change: new_freq=400
          kworker/u:0-28247 [000] .... 259391.581797: intel_gpu_freq_change: new_freq=350

        Returns:
            Dict with frequency in mhz as key and float in seconds for time
              spent at that frequency.
        """
        return self._trace_read_stats(self._I915_TRACE_CLK_RE)


class USBSuspendStats(AbstractStats):
    """
    USB active/suspend statistics (over all devices)
    """
    # TODO (snanda): handle hot (un)plugging of USB devices
    # TODO (snanda): handle duration counters wraparound

    def __init__(self):
        usb_stats_path = '/sys/bus/usb/devices/*/power'
        self._file_paths = glob.glob(usb_stats_path)
        if not self._file_paths:
            logging.debug('USB stats path not found')
        super(USBSuspendStats, self).__init__(name='usb')


    def _read_stats(self):
        usb_stats = {'active': 0, 'suspended': 0}

        for path in self._file_paths:
            active_duration_path = os.path.join(path, 'active_duration')
            total_duration_path = os.path.join(path, 'connected_duration')

            if not os.path.exists(active_duration_path) or \
               not os.path.exists(total_duration_path):
                logging.debug('duration paths do not exist for: %s', path)
                continue

            active = int(utils.read_file(active_duration_path))
            total = int(utils.read_file(total_duration_path))
            logging.debug('device %s active for %.2f%%',
                          path, active * 100.0 / total)

            usb_stats['active'] += active
            usb_stats['suspended'] += total - active

        return usb_stats


def get_cpu_sibling_groups():
    """
    Get CPU core groups in HMP systems.

    In systems with both small core and big core,
    returns groups of small and big sibling groups.
    """
    siblings_paths = '/sys/devices/system/cpu/cpu*/topology/' + \
                    'core_siblings_list'
    sibling_groups = []
    sibling_file_paths = glob.glob(siblings_paths)
    if not len(sibling_file_paths) > 0:
        return sibling_groups;
    total_cpus = len(sibling_file_paths)
    i = 0
    sibling_list_pattern = re.compile('(\d+)-(\d+)')
    while (i <  total_cpus):
        siblings_data = utils.read_file(sibling_file_paths[i])
        sibling_match = sibling_list_pattern.match(siblings_data)
        sibling_start, sibling_end = (int(x) for x in sibling_match.groups())
        sibling_groups.append((sibling_start, sibling_end))
        i = sibling_end + 1
    return sibling_groups



class StatoMatic(object):
    """Class to aggregate and monitor a bunch of power related statistics."""
    def __init__(self):
        self._start_uptime_secs = kernel_trace.KernelTrace.uptime_secs()
        self._astats = [USBSuspendStats(),
                        GPUFreqStats(incremental=False),
                        CPUPackageStats()]
        cpu_sibling_groups = get_cpu_sibling_groups()
        if not len(cpu_sibling_groups):
            self._astats.append(CPUFreqStats())
            self._astats.append(CPUIdleStats())
        for cpu_start, cpu_end in cpu_sibling_groups:
            self._astats.append(CPUFreqStats(cpu_start, cpu_end))
            self._astats.append(CPUIdleStats(cpu_start, cpu_end))
        if os.path.isdir(DevFreqStats._DIR):
            self._astats.extend([DevFreqStats(f) for f in \
                                 os.listdir(DevFreqStats._DIR)])

        self._disk = DiskStateLogger()
        self._disk.start()


    def publish(self):
        """Publishes results of various statistics gathered.

        Returns:
            dict with
              key = string 'percent_<name>_<key>_time'
              value = float in percent
        """
        results = {}
        tot_secs = kernel_trace.KernelTrace.uptime_secs() - \
            self._start_uptime_secs
        for stat_obj in self._astats:
            percent_stats = stat_obj.refresh()
            logging.debug("pstats = %s", percent_stats)
            if stat_obj.name is 'gpu':
                # TODO(tbroch) remove this once GPU freq stats have proved
                # reliable
                stats_secs = sum(stat_obj._stats.itervalues())
                if stats_secs < (tot_secs * 0.9) or \
                        stats_secs > (tot_secs * 1.1):
                    logging.warning('%s stats dont look right.  Not publishing.',
                                 stat_obj.name)
                    continue
            new_res = {}
            AbstractStats.format_results_percent(new_res, stat_obj.name,
                                                 percent_stats)
            wavg = stat_obj.weighted_average()
            if wavg:
                AbstractStats.format_results_wavg(new_res, stat_obj.name, wavg)

            results.update(new_res)

        new_res = {}
        if self._disk.get_error():
            new_res['disk_logging_error'] = str(self._disk.get_error())
        else:
            AbstractStats.format_results_percent(new_res, 'disk',
                                                 self._disk.result())
        results.update(new_res)

        return results


class PowerMeasurement(object):
    """Class to measure power.

    Public attributes:
        domain: String name of the power domain being measured.  Example is
          'system' for total system power

    Public methods:
        refresh: Performs any power/energy sampling and calculation and returns
            power as float in watts.  This method MUST be implemented in
            subclass.
    """

    def __init__(self, domain):
        """Constructor."""
        self.domain = domain


    def refresh(self):
        """Performs any power/energy sampling and calculation.

        MUST be implemented in subclass

        Returns:
            float, power in watts.
        """
        raise NotImplementedError("'refresh' method should be implemented in "
                                  "subclass.")


def parse_power_supply_info():
    """Parses power_supply_info command output.

    Command output from power_manager ( tools/power_supply_info.cc ) looks like
    this:

        Device: Line Power
          path:               /sys/class/power_supply/cros_ec-charger
          ...
        Device: Battery
          path:               /sys/class/power_supply/sbs-9-000b
          ...

    """
    rv = collections.defaultdict(dict)
    dev = None
    for ln in utils.system_output('power_supply_info').splitlines():
        logging.debug("psu: %s", ln)
        result = re.findall(r'^Device:\s+(.*)', ln)
        if result:
            dev = result[0]
            continue
        result = re.findall(r'\s+(.+):\s+(.+)', ln)
        if result and dev:
            kname = re.findall(r'(.*)\s+\(\w+\)', result[0][0])
            if kname:
                rv[dev][kname[0]] = result[0][1]
            else:
                rv[dev][result[0][0]] = result[0][1]

    return rv


class SystemPower(PowerMeasurement):
    """Class to measure system power.

    TODO(tbroch): This class provides a subset of functionality in BatteryStat
    in hopes of minimizing power draw.  Investigate whether its really
    significant and if not, deprecate.

    Private Attributes:
      _voltage_file: path to retrieve voltage in uvolts
      _current_file: path to retrieve current in uamps
    """

    def __init__(self, battery_dir):
        """Constructor.

        Args:
            battery_dir: path to dir containing the files to probe and log.
                usually something like /sys/class/power_supply/BAT0/
        """
        super(SystemPower, self).__init__('system')
        # Files to log voltage and current from
        self._voltage_file = os.path.join(battery_dir, 'voltage_now')
        self._current_file = os.path.join(battery_dir, 'current_now')


    def refresh(self):
        """refresh method.

        See superclass PowerMeasurement for details.
        """
        keyvals = parse_power_supply_info()
        return float(keyvals['Battery']['energy rate'])


class MeasurementLogger(threading.Thread):
    """A thread that logs measurement readings.

    Example code snippet:
         mylogger = MeasurementLogger([Measurent1, Measurent2])
         mylogger.run()
         for testname in tests:
             start_time = time.time()
             #run the test method for testname
             mlogger.checkpoint(testname, start_time)
         keyvals = mylogger.calc()

    Public attributes:
        seconds_period: float, probing interval in seconds.
        readings: list of lists of floats of measurements.
        times: list of floats of time (since Epoch) of when measurements
            occurred.  len(time) == len(readings).
        done: flag to stop the logger.
        domains: list of  domain strings being measured

    Public methods:
        run: launches the thread to gather measuremnts
        calc: calculates
        save_results:

    Private attributes:
       _measurements: list of Measurement objects to be sampled.
       _checkpoint_data: list of tuples.  Tuple contains:
           tname: String of testname associated with this time interval
           tstart: Float of time when subtest started
           tend: Float of time when subtest ended
       _results: list of results tuples.  Tuple contains:
           prefix: String of subtest
           mean: Float of mean  in watts
           std: Float of standard deviation of measurements
           tstart: Float of time when subtest started
           tend: Float of time when subtest ended
    """
    def __init__(self, measurements, seconds_period=1.0):
        """Initialize a logger.

        Args:
            _measurements: list of Measurement objects to be sampled.
            seconds_period: float, probing interval in seconds.  Default 1.0
        """
        threading.Thread.__init__(self)

        self.seconds_period = seconds_period

        self.readings = []
        self.times = []
        self._checkpoint_data = []

        self.domains = []
        self._measurements = measurements
        for meas in self._measurements:
            self.domains.append(meas.domain)

        self.done = False


    def run(self):
        """Threads run method."""
        while(not self.done):
            readings = []
            for meas in self._measurements:
                readings.append(meas.refresh())
            # TODO (dbasehore): We probably need proper locking in this file
            # since there have been race conditions with modifying and accessing
            # data.
            self.readings.append(readings)
            self.times.append(time.time())
            time.sleep(self.seconds_period)


    def checkpoint(self, tname='', tstart=None, tend=None):
        """Check point the times in seconds associated with test tname.

        Args:
           tname: String of testname associated with this time interval
           tstart: Float in seconds of when tname test started.  Should be based
                off time.time()
           tend: Float in seconds of when tname test ended.  Should be based
                off time.time().  If None, then value computed in the method.
        """
        if not tstart and self.times:
            tstart = self.times[0]
        if not tend:
            tend = time.time()
        self._checkpoint_data.append((tname, tstart, tend))
        logging.info('Finished test "%s" between timestamps [%s, %s]',
                     tname, tstart, tend)


    def calc(self, mtype=None):
        """Calculate average measurement during each of the sub-tests.

        Method performs the following steps:
            1. Signals the thread to stop running.
            2. Calculates mean, max, min, count on the samples for each of the
               measurements.
            3. Stores results to be written later.
            4. Creates keyvals for autotest publishing.

        Args:
            mtype: string of measurement type.  For example:
                   pwr == power
                   temp == temperature

        Returns:
            dict of keyvals suitable for autotest results.
        """
        if not mtype:
            mtype = 'meas'

        t = numpy.array(self.times)
        keyvals = {}
        results  = []

        if not self.done:
            self.done = True
        # times 2 the sleep time in order to allow for readings as well.
        self.join(timeout=self.seconds_period * 2)

        if not self._checkpoint_data:
            self.checkpoint()

        for i, domain_readings in enumerate(zip(*self.readings)):
            meas = numpy.array(domain_readings)
            domain = self.domains[i]

            for tname, tstart, tend in self._checkpoint_data:
                if tname:
                    prefix = '%s_%s' % (tname, domain)
                else:
                    prefix = domain
                keyvals[prefix+'_duration'] = tend - tstart
                # Select all readings taken between tstart and tend timestamps.
                # Try block just in case
                # code.google.com/p/chromium/issues/detail?id=318892
                # is not fixed.
                try:
                    meas_array = meas[numpy.bitwise_and(tstart < t, t < tend)]
                except ValueError, e:
                    logging.debug('Error logging measurements: %s', str(e))
                    logging.debug('timestamps %d %s' % (t.len, t))
                    logging.debug('timestamp start, end %f %f' % (tstart, tend))
                    logging.debug('measurements %d %s' % (meas.len, meas))

                # If sub-test terminated early, avoid calculating avg, std and
                # min
                if not meas_array.size:
                    continue
                meas_mean = meas_array.mean()
                meas_std = meas_array.std()

                # Results list can be used for pretty printing and saving as csv
                results.append((prefix, meas_mean, meas_std,
                                tend - tstart, tstart, tend))

                keyvals[prefix + '_' + mtype] = meas_mean
                keyvals[prefix + '_' + mtype + '_cnt'] = meas_array.size
                keyvals[prefix + '_' + mtype + '_max'] = meas_array.max()
                keyvals[prefix + '_' + mtype + '_min'] = meas_array.min()
                keyvals[prefix + '_' + mtype + '_std'] = meas_std

        self._results = results
        return keyvals


    def save_results(self, resultsdir, fname=None):
        """Save computed results in a nice tab-separated format.
        This is useful for long manual runs.

        Args:
            resultsdir: String, directory to write results to
            fname: String name of file to write results to
        """
        if not fname:
            fname = 'meas_results_%.0f.txt' % time.time()
        fname = os.path.join(resultsdir, fname)
        with file(fname, 'wt') as f:
            for row in self._results:
                # First column is name, the rest are numbers. See _calc_power()
                fmt_row = [row[0]] + ['%.2f' % x for x in row[1:]]
                line = '\t'.join(fmt_row)
                f.write(line + '\n')


class PowerLogger(MeasurementLogger):
    def save_results(self, resultsdir, fname=None):
        if not fname:
            fname = 'power_results_%.0f.txt' % time.time()
        super(PowerLogger, self).save_results(resultsdir, fname)


    def calc(self, mtype='pwr'):
        return super(PowerLogger, self).calc(mtype)


class TempMeasurement(object):
    """Class to measure temperature.

    Public attributes:
        domain: String name of the temperature domain being measured.  Example is
          'cpu' for cpu temperature

    Private attributes:
        _path: Path to temperature file to read ( in millidegrees Celsius )

    Public methods:
        refresh: Performs any temperature sampling and calculation and returns
            temperature as float in degrees Celsius.
    """
    def __init__(self, domain, path):
        """Constructor."""
        self.domain = domain
        self._path = path


    def refresh(self):
        """Performs temperature

        Returns:
            float, temperature in degrees Celsius
        """
        return int(utils.read_one_line(self._path)) / 1000.


class TempLogger(MeasurementLogger):
    """A thread that logs temperature readings in millidegrees Celsius."""
    def __init__(self, measurements, seconds_period=30.0):
        if not measurements:
            measurements = []
            tstats = ThermalStatHwmon()
            for kname in tstats.fields:
                match = re.match(r'(\S+)_temp(\d+)_input', kname)
                if not match:
                    continue
                domain = match.group(1) + '-t' + match.group(2)
                fpath = tstats.fields[kname][0]
                new_meas = TempMeasurement(domain, fpath)
                measurements.append(new_meas)
        super(TempLogger, self).__init__(measurements, seconds_period)


    def save_results(self, resultsdir, fname=None):
        if not fname:
            fname = 'temp_results_%.0f.txt' % time.time()
        super(TempLogger, self).save_results(resultsdir, fname)


    def calc(self, mtype='temp'):
        return super(TempLogger, self).calc(mtype)


class DiskStateLogger(threading.Thread):
    """Records the time percentages the disk stays in its different power modes.

    Example code snippet:
        mylogger = power_status.DiskStateLogger()
        mylogger.start()
        result = mylogger.result()

    Public methods:
        start: Launches the thread and starts measurements.
        result: Stops the thread if it's still running and returns measurements.
        get_error: Returns the exception in _error if it exists.

    Private functions:
        _get_disk_state: Returns the disk's current ATA power mode as a string.

    Private attributes:
        _seconds_period: Disk polling interval in seconds.
        _stats: Dict that maps disk states to seconds spent in them.
        _running: Flag that is True as long as the logger should keep running.
        _time: Timestamp of last disk state reading.
        _device_path: The file system path of the disk's device node.
        _error: Contains a TestError exception if an unexpected error occured
    """
    def __init__(self, seconds_period = 5.0, device_path = None):
        """Initializes a logger.

        Args:
            seconds_period: Disk polling interval in seconds. Default 5.0
            device_path: The path of the disk's device node. Default '/dev/sda'
        """
        threading.Thread.__init__(self)
        self._seconds_period = seconds_period
        self._device_path = device_path
        self._stats = {}
        self._running = False
        self._error = None

        result = utils.system_output('rootdev -s')
        # TODO(tbroch) Won't work for emmc storage and will throw this error in
        # keyvals : 'ioctl(SG_IO) error: [Errno 22] Invalid argument'
        # Lets implement something complimentary for emmc
        if not device_path:
            self._device_path = \
                re.sub('(sd[a-z]|mmcblk[0-9]+)p?[0-9]+', '\\1', result)
        logging.debug("device_path = %s", self._device_path)


    def start(self):
        logging.debug("inside DiskStateLogger.start")
        if os.path.exists(self._device_path):
            logging.debug("DiskStateLogger started")
            super(DiskStateLogger, self).start()


    def _get_disk_state(self):
        """Checks the disk's power mode and returns it as a string.

        This uses the SG_IO ioctl to issue a raw SCSI command data block with
        the ATA-PASS-THROUGH command that allows SCSI-to-ATA translation (see
        T10 document 04-262r8). The ATA command issued is CHECKPOWERMODE1,
        which returns the device's current power mode.
        """

        def _addressof(obj):
            """Shortcut to return the memory address of an object as integer."""
            return ctypes.cast(obj, ctypes.c_void_p).value

        scsi_cdb = struct.pack("12B", # SCSI command data block (uint8[12])
                               0xa1, # SCSI opcode: ATA-PASS-THROUGH
                               3 << 1, # protocol: Non-data
                               1 << 5, # flags: CK_COND
                               0, # features
                               0, # sector count
                               0, 0, 0, # LBA
                               1 << 6, # flags: ATA-USING-LBA
                               0xe5, # ATA opcode: CHECKPOWERMODE1
                               0, # reserved
                               0, # control (no idea what this is...)
                              )
        scsi_sense = (ctypes.c_ubyte * 32)() # SCSI sense buffer (uint8[32])
        sgio_header = struct.pack("iiBBHIPPPIIiPBBBBHHiII", # see <scsi/sg.h>
                                  83, # Interface ID magic number (int32)
                                  -1, # data transfer direction: none (int32)
                                  12, # SCSI command data block length (uint8)
                                  32, # SCSI sense data block length (uint8)
                                  0, # iovec_count (not applicable?) (uint16)
                                  0, # data transfer length (uint32)
                                  0, # data block pointer
                                  _addressof(scsi_cdb), # SCSI CDB pointer
                                  _addressof(scsi_sense), # sense buffer pointer
                                  500, # timeout in milliseconds (uint32)
                                  0, # flags (uint32)
                                  0, # pack ID (unused) (int32)
                                  0, # user data pointer (unused)
                                  0, 0, 0, 0, 0, 0, 0, 0, 0, # output params
                                 )
        try:
            with open(self._device_path, 'r') as dev:
                result = fcntl.ioctl(dev, 0x2285, sgio_header)
        except IOError, e:
            raise error.TestError('ioctl(SG_IO) error: %s' % str(e))
        _, _, _, _, status, host_status, driver_status = \
            struct.unpack("4x4xxx2x4xPPP4x4x4xPBxxxHH4x4x4x", result)
        if status != 0x2: # status: CHECK_CONDITION
            raise error.TestError('SG_IO status: %d' % status)
        if host_status != 0:
            raise error.TestError('SG_IO host status: %d' % host_status)
        if driver_status != 0x8: # driver status: SENSE
            raise error.TestError('SG_IO driver status: %d' % driver_status)

        if scsi_sense[0] != 0x72: # resp. code: current error, descriptor format
            raise error.TestError('SENSE response code: %d' % scsi_sense[0])
        if scsi_sense[1] != 0: # sense key: No Sense
            raise error.TestError('SENSE key: %d' % scsi_sense[1])
        if scsi_sense[7] < 14: # additional length (ATA status is 14 - 1 bytes)
            raise error.TestError('ADD. SENSE too short: %d' % scsi_sense[7])
        if scsi_sense[8] != 0x9: # additional descriptor type: ATA Return Status
            raise error.TestError('SENSE descriptor type: %d' % scsi_sense[8])
        if scsi_sense[11] != 0: # errors: none
            raise error.TestError('ATA error code: %d' % scsi_sense[11])

        if scsi_sense[13] == 0x00:
            return 'standby'
        if scsi_sense[13] == 0x80:
            return 'idle'
        if scsi_sense[13] == 0xff:
            return 'active'
        return 'unknown(%d)' % scsi_sense[13]


    def run(self):
        """The Thread's run method."""
        try:
            self._time = time.time()
            self._running = True
            while(self._running):
                time.sleep(self._seconds_period)
                state = self._get_disk_state()
                new_time = time.time()
                if state in self._stats:
                    self._stats[state] += new_time - self._time
                else:
                    self._stats[state] = new_time - self._time
                self._time = new_time
        except error.TestError, e:
            self._error = e
            self._running = False


    def result(self):
        """Stop the logger and return dict with result percentages."""
        if (self._running):
            self._running = False
            self.join(self._seconds_period * 2)
        return AbstractStats.to_percent(self._stats)


    def get_error(self):
        """Returns the _error exception... please only call after result()."""
        return self._error
