# Lint as: python2, python3
# Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""A Python library to interact with INA219 module for TPM testing.

Background
 - INA219 is one of two modules on TTCI board
 - This library provides methods to interact with INA219 programmatically

Dependency
 - This library depends on a new C shared library called "libsmogcheck.so".
 - In order to run test cases built using this API, one needs a TTCI board

Notes:
 - An exception is raised if it doesn't make logical sense to continue program
   flow (e.g. I/O error prevents test case from executing)
 - An exception is caught and then converted to an error code if the caller
   expects to check for error code per API definition
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import logging, re
from autotest_lib.client.common_lib import i2c_node
import six


# INA219 registers
INA_REG = {
    'CONF': 0,        # Configuration Register
    'SHUNT_VOLT': 1,  # Shunt Voltage
    'BUS_VOLT': 2,    # Bus Voltage
    'POWER': 3,       # Power
    'CURRENT': 4,     # Current
    'CALIB': 5,       # Calibration
    }

# Regex pattern for measurement value
HEX_STR_PATTERN = re.compile('^0x([0-9a-f]{2})([0-9a-f]{2})$')

# Constants used to initialize INA219 registers
# TODO(tgao): add docstring for these values after stevenh replies
INA_CONF_INIT_VAL = 0x9f31
INA_CALIB_INIT_VAL = 0xc90e

# Default values used to calculate/interpret voltage and current measurements.
DEFAULT_MEAS_RANGE_VALUE = {
    'current': {'max': 0.1, 'min': 0.0, 'denom': 10000.0,
                'reg': INA_REG['CURRENT']},
    'voltage': {'max': 3.35, 'min': 3.25, 'denom': 2000.0,
                'reg': INA_REG['BUS_VOLT']},
    }


class InaError(Exception):
    """Base class for all errors in this module."""


class InaController(i2c_node.I2cNode):
    """Object to control INA219 module on TTCI board."""

    def __init__(self, node_addr=None, range_dict=None):
        """Constructor.

        Mandatory params:
          node_addr: node address to set. Default: None.

        Optional param:
          range_dict: desired max/min thresholds for measurement values.
                      Default: DEFAULT_MEAS_RANGE_VALUE.

        Args:
          node_addr: an integer, address of main or backup power.
          range_dict: desired max/min thresholds for measurement values.

        Raises:
          InaError: if error initializing INA219 module or invalid range_dict.
        """
        super(InaController, self).__init__()
        if node_addr is None:
            raise InaError('Error node_addr expected')

        try:
            if range_dict is None:
                range_dict = DEFAULT_MEAS_RANGE_VALUE
            else:
                self._validateRangeDict(DEFAULT_MEAS_RANGE_VALUE, range_dict)
            self.range_dict = range_dict

            self.setNodeAddress(node_addr)
            self.writeWord(INA_REG['CONF'], INA_CONF_INIT_VAL)
            self.writeWord(INA_REG['CALIB'], INA_CALIB_INIT_VAL)
        except InaError as e:
            raise InaError('Error initializing INA219: %s' % e)

    def _validateRangeDict(self, d_ref, d_in):
        """Validates keys and types of value in range_dict.

        Iterate over d_ref to make sure all keys exist in d_in and
        values are of the correct type.

        Args:
          d_ref: a dictionary, used as reference.
          d_in: a dictionary, to be validated against reference.

        Raises:
          InaError: if range_dict is invalid.
        """
        for k, v in six.iteritems(d_ref):
            if k not in d_in:
                raise InaError('Key %s not present in dict %r' % (k, d_in))
            if type(v) != type(d_in[k]):
                raise InaError(
                    'Value type mismatch for key %s. Expected: %s; actual = %s'
                    % (k, type(v), type(d_in[k])))
            if type(v) is dict:
                self._validateRangeDict(v, d_in[k])

    def readMeasure(self, measure):
        """Reads requested measurement.

        Args:
          measure: a string, 'current' or 'voltage'.

        Returns:
          a float, measurement in units. Or None if error.

        Raises:
          InaError: if error reading requested measurement.
        """
        try:
            hex_str = '0x%.4x' % self.readWord(self.range_dict[measure]['reg'])
            logging.debug('Word read = %r', hex_str)
            return self._checkMeasureRange(hex_str, measure)
        except InaError as e:
            logging.error('Error reading %s: %s', measure, e)

    def getPowerMetrics(self):
        """Get measurement metrics for Main Power.

        Returns:
          an integer, 0 for success and -1 for error.
          a float, voltage value in Volts. Or None if error.
          a float, current value in Amps. Or None if error.
        """
        logging.info('Attempt to get power metrics')
        try:
            return (0, self.readMeasure('voltage'),
                    self.readMeasure('current'))
        except InaError as e:
            logging.error('getPowerMetrics(): %s', e)
            return (-1, None, None)

    def _checkMeasureRange(self, hex_str, measure):
        """Checks if measurement value falls within a pre-specified range.

        Args:
          hex_str: a string (hex value).
          measure: a string, 'current' or 'voltage'.

        Returns:
          measure_float: a float, measurement value.

        Raises:
          InaError: if value doesn't fall in range.
        """
        measure_float = self._convertHexToFloat(
            hex_str, self.range_dict[measure]['denom'])
        measure_msg = '%s value %.2f' % (measure, measure_float)
        range_msg = '[%(min).2f, %(max).2f]' % self.range_dict[measure]
        if (measure_float < self.range_dict[measure]['min'] or
            measure_float > self.range_dict[measure]['max']):
            raise InaError('%s is out of range %s' % measure_msg, range_msg)
        logging.info('%s is in range %s', measure_msg, range_msg)
        return measure_float

    def _convertHexToFloat(self, hex_str, denom):
        """Performs measurement calculation.

        The measurement reading from INA219 module is a 2-byte hex string.
        To convert this hex string to a float, we need to swap these two bytes
        and perform a division. An example:
          response = 0xca19
          swap bytes to get '0x19ca'
          convert to decimal value = 6602
          divide decimal by 2000.0 = 3.301 (volts)

        Args:
          hex_str: a string (raw hex value).
          denom: a float, denominator used for hex-to-float conversion.

        Returns:
          a float, measurement value.

        Raises:
          InaError: if error converting measurement to float.
        """
        match = HEX_STR_PATTERN.match(hex_str)
        if not match:
            raise InaError('Error: hex string %s does not match '
                           'expected pattern' % hex_str)

        decimal = int('0x%s%s' % (match.group(2), match.group(1)), 16)
        return decimal/denom
