# Copyright 2016 Google Inc.
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import time

class Hardware:
  """Locks down and monitors hardware for benchmarking.

  This is a common base for classes that can control the specific hardware
  we are running on. Its purpose is to lock the hardware into a constant
  benchmarking mode for the duration of a 'with' block. e.g.:

    with hardware:
      run_benchmark()

  While benchmarking, the caller must call sanity_check() frequently to verify
  the hardware state has not changed.

  """

  def __init__(self):
    self.warmup_time = 0

  def __enter__(self):
    return self

  def __exit__(self, exception_type, exception_value, traceback):
    pass

  def filter_line(self, line):
    """Returns False if the provided output line can be suppressed."""
    return True

  def sanity_check(self):
    """Raises a HardwareException if any hardware state is not as expected."""
    pass

  def print_debug_diagnostics(self):
    """Prints any info that may help improve or debug hardware monitoring."""
    pass


class HardwareException(Exception):
  """Gets thrown when certain hardware state is not what we expect.

  Generally this happens because of thermal conditions or other variables beyond
  our control, and the appropriate course of action is to take a short nap
  before resuming the benchmark.

  """

  def __init__(self, message, sleeptime=60):
    Exception.__init__(self, message)
    self.sleeptime = sleeptime


class Expectation:
  """Simple helper for checking the readings on hardware gauges."""
  def __init__(self, value_type, min_value=None, max_value=None,
               exact_value=None, name=None, sleeptime=60):
    self.value_type = value_type
    self.min_value = min_value
    self.max_value = max_value
    self.exact_value = exact_value
    self.name = name
    self.sleeptime = sleeptime

  def check(self, stringvalue):
    typedvalue = self.value_type(stringvalue)
    if self.min_value is not None and typedvalue < self.min_value:
       raise HardwareException("%s is too low (%s, min=%s)" %
                               (self.name, stringvalue, str(self.min_value)),
                               sleeptime=self.sleeptime)
    if self.max_value is not None and typedvalue > self.max_value:
       raise HardwareException("%s is too high (%s, max=%s)" %
                               (self.name, stringvalue, str(self.max_value)),
                               sleeptime=self.sleeptime)
    if self.exact_value is not None and typedvalue != self.exact_value:
       raise HardwareException("unexpected %s (%s, expected=%s)" %
                               (self.name, stringvalue, str(self.exact_value)),
                               sleeptime=self.sleeptime)

  @staticmethod
  def check_all(expectations, stringvalues):
    if len(stringvalues) != len(expectations):
      raise Exception("unexpected reading from hardware gauges "
                      "(expected %i values):\n%s" %
                      (len(expectations), '\n'.join(stringvalues)))

    for value, expected in zip(stringvalues, expectations):
      expected.check(value)
