# Copyright 2018 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.

"""Helper class for power autotests requiring telemetry devices."""

import logging
import time

import numpy

class TelemetryUtilsError(Exception):
    """Error class for issues using these utilities."""

INTERPOLATION_RESOLUTION = 6

def interpolate_missing_data(data, max_nan_ratio=None, max_sample_gap=None,
                             max_sample_time_gap=None, timeline=None):
    """Interpolate missing power readings in data.

    @param data: array of values
    @min_nan_ratio: optional, float, max acceptable ratio of NaN to real values
    @max_sample_gap: optional, int, max acceptable number of NaN in a row
    @max_sample_time_gap: optional, float, max measurement gap in seconds
                       Note: supplying max_nan_time_gap requires timeline
    @timeline: array of same size as |data| with timeline info for each sample

    @returns: list, array |data| with missing values interpolated.
    @raises: TelemetryUtilsError if
              - the ratio of NaN is higher than |max_nan_ratio| (if supplied)
              - no NaN gap is larger than |max_sample_gap| (if supplied)
              - no NaN gap takes more time in |timeline| than
                |max_sample_time_gap| (if supplied)
              - all values in |data| are NaN.
    """
    if max_sample_time_gap is not None and timeline is None:
        # These are mutually required.
        raise TelemetryUtilsError('Supplying max_sample_time_gap requires a '
                                  'timeline.')
    data = numpy.array(data)
    nan_data = numpy.isnan(data)
    if max_nan_ratio:
        # Validate the ratio if a ratio is supplied.
        nan_ratio = float(sum(nan_data)) / len(data)
        if nan_ratio > max_nan_ratio:
            # There are too many errors in this source.
            # Throw an error so the user has a chance to adjust their power
            # collection setup.
            raise TelemetryUtilsError('NaN ratio of %.02f '
                                      ' - Max is %.02f.' % (nan_ratio,
                                                            max_nan_ratio))
    if max_sample_gap is not None or max_sample_time_gap is not None:
        # Flag to keep track whether the loop is in a measurement gap (NaN).
        consecutive_nan_start = None
        # Add a dummy at the end to make sure the iteration covers all real
        # examples.
        for i, isnan in enumerate(numpy.append(nan_data, False)):
            if isnan and consecutive_nan_start is None:
                consecutive_nan_start = i
            if not isnan and consecutive_nan_start is not None:
                consecutive_nans = i - consecutive_nan_start
                if max_sample_gap and consecutive_nans >= max_sample_gap:
                    # Reject if there are too many consecutive failures.
                    raise TelemetryUtilsError('Too many consecutive NaN samples'
                                              ': %d.' % consecutive_nans)
                if max_sample_time_gap:
                    # Checks whether the first valid timestamp before the
                    # gap exists and whether the first valid timestamp after the
                    # gap exists.
                    if consecutive_nan_start == 0 or i == len(data):
                        # We cannot determine the gap timeline properly here
                        # as the gap either starts or ends with the time.
                        # Ignore for now.
                        continue
                    sample_time_gap = (timeline[i] -
                                       timeline[consecutive_nan_start-1])
                    if sample_time_gap > max_sample_time_gap:
                        raise TelemetryUtilsError('Excessively long sample gap '
                                                  'of %.02fs. Longest '
                                                  'permissible gap is %.02fs.'
                                                  % (sample_time_gap,
                                                     max_sample_time_gap))

                # Reset the flag for the next gap.
                consecutive_nan_start = None
    # At this point the data passed all validations required.
    sample_idx = numpy.arange(len(data))[[~nan_data]]
    sample_vals = data[[~nan_data]]
    if not len(sample_idx):
        raise TelemetryUtilsError('Data has no valid readings. Cannot '
                                  'interpolate.')
    output = numpy.interp(range(len(data)), sample_idx, sample_vals)
    return [round(x, INTERPOLATION_RESOLUTION) for x in output]

CUSTOM_START = 'PowerTelemetryLogger custom start.'
CUSTOM_END = 'PowerTelemetryLogger custom end.'


def log_event_ts(message=None, timestamp=None, offset=0):
    """Log the event and timestamp for parsing later.

    @param message: description of the event.
    @param timestamp: timestamp to for the event, if not provided, default to
           current time. Local seconds since epoch.
    @param offset: offset in seconds from the provided timestamp, or offset from
           current time if timestamp is not provided. Can be positive or
           negative.
    """
    if not message:
        return
    if timestamp:
        ts = timestamp + offset
    else:
        ts = time.time() + offset
    logging.debug("%s %s", message, ts)

def start_measurement(timestamp=None, offset=0):
    """Mark the start of power telemetry measurement.

    Optional. Use only once in the client side test that is wrapped in
    power_MeasurementWrapper to help pinpoint exactly where power telemetry
    data should start. PowerTelemetryLogger will trim off excess data before
    this point. If not used, power telemetry data will start right before the
    client side test.
    @param timestamp: timestamp for the start of measurement, if not provided,
           default to current time. Local seconds since epoch.
    @param offset: offset in seconds from the provided timestamp, or offset from
           current time if timestamp is not provided. Can be positive or
           negative.
    """
    log_event_ts(CUSTOM_START, timestamp, offset)

def end_measurement(timestamp=None, offset=0):
    """Mark the end of power telemetry measurement.

    Optional. Use only once in the client side test that is wrapped in
    power_MeasurementWrapper to help pinpoint exactly where power telemetry
    data should end. PowerTelemetryLogger will trim off excess data after
    this point. If not used, power telemetry data will end right after the
    client side test.
    @param timestamp: timestamp for the end of measurement, if not provided,
           default to current time. Local seconds since epoch.
    @param offset: offset in seconds from the provided timestamp, or offset from
           current time if timestamp is not provided. Can be positive or
           negative.
    """
    log_event_ts(CUSTOM_END, timestamp, offset)
