<!DOCTYPE html>
<!--
Copyright (c) 2015 The Chromium Authors. All rights reserved.
Use of this source code is governed by a BSD-style license that can be
found in the LICENSE file.
-->

<link rel="import" href="/core/importer/importer.html">
<link rel="import" href="/core/trace_model/trace_model.html">

<script>
/**
 * @fileoverview Imports text files in the BattOr format into the
 * Tracemodel. This format is output by the BattOr executable
 *
 * This importer assumes the events arrive as a string. The unit tests provide
 * examples of the trace format.
 */
'use strict';

tv.exportTo('tv.e.importer.battor', function() {
  var Importer = tv.c.importer.Importer;

  /**
   * Imports linux perf events into a specified model.
   * @constructor
   */
  function BattorImporter(model, events) {
    this.importPriority = 3; // runs after the linux_perf importer
    this.series_ = undefined;
    this.sampleRate_ = undefined;
    this.model_ = model;
    this.events_ = events;
    this.kernelThreadStates_ = {};
    this.lines_ = [];
    this.pseudoThreadCounter = 1;
  }

  var TestExports = {};

  var battorLineRE = /^(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)$/;
  var sampleRateLineRE = /^# sample_rate=(\d+)Hz/;

  /**
   * Guesses whether the provided events is a BattOr string.
   * Looks for the magic string "# BattOr" at the start of the file,
   *
   * @return {boolean} True when events is a BattOr array.
   */
  BattorImporter.canImport = function(events) {
    if (!(typeof(events) === 'string' || events instanceof String))
      return false;

    if (/^# BattOr/.test(events))
      return true;

    return false;
  };

  BattorImporter.prototype = {
    __proto__: Importer.prototype,

    get model() {
      return this.model_;
    },

    /**
     * Imports the data in this.events_ into model_.
     */
    importEvents: function(isSecondaryImport) {
      // Create series and import power samples into it.
      var name = 'power';
      var series = new tv.c.trace_model.CounterSeries('value',
          tv.b.ui.getColorIdForGeneralPurposeString(name + '.' + 'value'));
      this.importPowerSamples(series);
      this.series_ = series;

      // Find the markers for the beginning and end of the vreg sync.
      var syncMarks = this.model_.getClockSyncRecordsNamed('battor');
      if (syncMarks.length < 2) {
        this.model_.importWarning({
          type: 'clock_sync',
          message: 'Cannot import BattOr measurments without a sync signal.'
        });
        return;
      }

      // Find the regulator counter for the sync.
      var syncCtr = this.model_.kernel.counters[
          'null.vreg ' + syncMarks[0].args['regulator'] + ' enabled'];
      if (syncCtr === undefined) {
        this.model_.importWarning({
          type: 'clock_sync',
          message: 'Cannot import BattOr power trace without sync vreg.'
        });
        return;
      }

      // Store the sync events from the regulator counter.
      var syncEvents = [];
      var firstSyncEventTs = undefined;
      syncCtr.series[0].iterateAllEvents(function(event) {
        if (event.timestamp >= syncMarks[0].ts &&
            event.timestamp <= syncMarks[1].ts) {
          if (firstSyncEventTs === undefined)
            firstSyncEventTs = event.timestamp;
          var newEvent = {
              'ts': (event.timestamp - firstSyncEventTs) / 1000, // msec -> sec
              'val': event.value};
          syncEvents.push(newEvent);
        }
      });

      // Generate samples from sync events to be cross-correlated with power.
      var syncSamples = [];
      var syncNumSamples = Math.ceil(
          syncEvents[syncEvents.length - 1].ts * this.sampleRate_
      );

      for (var i = 1; i < syncEvents.length; i++) {
        var sampleStartIdx = Math.ceil(
            syncEvents[i - 1].ts * this.sampleRate_
        );
        var sampleEndIdx = Math.ceil(
            syncEvents[i].ts * this.sampleRate_
        );

        for (var j = sampleStartIdx; j < sampleEndIdx; j++) {
          syncSamples[j] = syncEvents[i - 1].val;
        }
      }

      // TODO(aschulman) Low-pass the samples to improve the cross-correlation.

      var powerSamples = series.samples;
      // Check to make sure there are enough power samples.
      if (powerSamples.length < syncSamples.length) {
        this.model_.importWarning({
          type: 'not_enough_samples',
          message: 'Not enough power samples to correlate with sync signal.'
        });
        return;
      }

      // Cross-correlate the ground truth with the last 5s of power samples.
      var maxShift = powerSamples.length - syncSamples.length;
      var minShift = 0;
      var corrNumSamples = this.sampleRate_ * 5.0;
      if (powerSamples.length > corrNumSamples)
        minShift = powerSamples.length - corrNumSamples;

      var corr = [];
      for (var shift = minShift; shift <= maxShift; shift++) {
        var corrSum = 0;
        var powerAvg = 0;
        for (var i = 0; i < syncSamples.length; i++) {
          corrSum += (powerSamples[i + shift].value * syncSamples[i]);
          powerAvg += powerSamples[i + shift].value;
        }
        powerAvg = powerAvg / syncSamples.length;
        corr.push(corrSum / powerAvg);
      }

      // Find the sync start time (peak of the cross-correlation).
      var corrPeakIdx = 0;
      var corrPeak = 0;
      for (var i = 0; i < powerSamples.length; i++) {
        if (corr[i] > corrPeak) {
          corrPeak = corr[i];
          corrPeakIdx = i;
        }
      }

      // Add a counter for power to the GUI.
      var ctr = this.model_.kernel.getOrCreateCounter(null, 'Power');
      if (ctr.numSeries === 0) {
        ctr.addSeries(series);
      }
      this.counter_ = ctr;

      // Shift the time of the power samples by the recovered sync start time.
      var corrPeakTs = ((minShift + corrPeakIdx) / this.sampleRate_);
      corrPeakTs *= 1000; // sec -> msec
      var syncStartTs = firstSyncEventTs - this.model_.bounds.min;
      var shiftTs = syncStartTs - corrPeakTs;
      this.counter_.shiftTimestampsForward(shiftTs);
    },

    /**
     * Walks the events and populates a time series with power samples.
     */
    importPowerSamples: function(series) {
      var lines = this.events_.split('\n');

      // Update the model's bounds.
      this.model_.updateBounds();
      var minTs = 0;
      if (this.model_.bounds.min !== undefined)
        minTs = this.model_.bounds.min;

      lines.forEach(function(line) {
        if (line.length == 0)
          return;

        if (/^#/.test(line)) {
          // Parse sample rate.
          groups = sampleRateLineRE.exec(line);
          if (!groups)
            return;
          this.sampleRate_ = parseInt(groups[1]);
        } else {
          // Parse power sample.
          var groups = battorLineRE.exec(line);
          if (!groups) {
            this.model_.importWarning({
                type: 'parse_error',
                message: 'Unrecognized line: ' + line
            });
            return;
          }

          var time = parseFloat(groups[1]) + minTs;
          var voltage_mV = parseFloat(groups[2]);
          var current_mA = parseFloat(groups[3]);
          series.addCounterSample(time, (voltage_mV * current_mA) / 1000);
        }
      }, this);
    }
  };

  tv.c.importer.Importer.register(BattorImporter);

  return {
    BattorImporter: BattorImporter,
    _BattorImporterTestExports: TestExports
  };
});

</script>
