#!/usr/bin/python -S

"""Utility for ensuring a series of events occur or time out."""

import logging
import os
import time

# This has to be called before another module calls it with a higher log level.
# pylint: disable=g-import-not-at-top
logging.basicConfig(level=logging.DEBUG)


class TimeoutException(Exception):
  pass


class Condition(object):
  """Wrapper for a function that may time out."""

  def __init__(self, name, evaluate, timeout, logger=None, callback=None):
    self.name = name
    if evaluate:
      self.evaluate = evaluate
    self.timeout = timeout
    self.logger = logger or logging
    self.callback = callback
    self.reset()

  def reset(self, t0=None, start_at=None):
    """Reset the Condition to an initial state.

    Takes two different timestamp values to account for uncertainty in when a
    previous condition may have been met.

    Args:
      t0:  The timestamp after which to evaluate the condition.
      start_at:  The timestamp from which to compute the timeout.
    """
    self.t0 = t0 or time.time()
    self.start_at = start_at or time.time()
    self.done_after = None
    self.done_by = None
    self.timed_out = False
    self.not_done_before = self.t0

  def check(self):
    """Check whether the condition has completed or timed out."""
    if self.timed_out:
      raise TimeoutException()

    if self.done_after:
      return True

    if self.evaluate():
      self.mark_done()
      return True

    now = time.time()
    if now > self.start_at + self.timeout:
      self.timed_out = True
      self.logger.info('%s timed out after %.2f seconds',
                       self.name, now - self.t0)
      raise TimeoutException()

    self.not_done_before = time.time()
    return False

  def mark_done(self):
    # In general, we don't know when a condition finished, but we know it was
    # *after* whenever it was most recently not done.
    self.done_after = self.not_done_before
    self.done_by = time.time()
    self.logger.info('%s completed after %.2f seconds',
                     self.name, self.done_by - self.t0)

    if self.callback:
      self.callback()


class FileExistsCondition(Condition):
  """A condition that checks for the existence of a file."""

  def __init__(self, name, filename, timeout):
    self._filename = filename
    super(FileExistsCondition, self).__init__(name, None, timeout)

  def evaluate(self):
    return os.path.exists(self._filename)

  def mtime(self):
    if os.path.exists(self._filename):
      return os.stat(self._filename).st_mtime

    return None

  def mark_done(self):
    super(FileExistsCondition, self).mark_done()
    # We have to check this because the file could have been deleted while this
    # was being called.  But this condition should almost always be true.
    mtime = self.mtime()
    if mtime:
      self.done_after = self.done_by = mtime


class FileTouchedCondition(FileExistsCondition):
  """A condition that checks that a file was touched after a certain time."""

  def reset(self, t0=None, start_at=None):
    mtime = self.mtime
    if t0 and mtime and mtime < t0:
      self.initial_mtime = self.mtime()
    else:
      self.initial_mtime = None
    super(FileTouchedCondition, self).reset(t0, start_at)

  def evaluate(self):
    if not super(FileTouchedCondition, self).evaluate():
      return False

    if self.initial_mtime:
      return self.mtime() > self.initial_mtime

    return self.mtime() >= self.t0


class Ratchet(Condition):
  """A condition that comprises a series of subconditions."""

  def __init__(self, name, steps, status):
    self.name = name
    self.steps = steps
    for step in self.steps:
      step.logger = logging.getLogger(self.name)
    self._status = status
    super(Ratchet, self).__init__(name, None, 0)

  def reset(self):
    self._current_step = 0
    for step in self.steps:
      step.reset()
      self._set_step_status(step, False)
    self._set_current_step_status(True)
    super(Ratchet, self).reset()

  # Override check rather than evaluate because we don't want the Ratchet to
  # time out unless one of its steps does.
  def check(self):
    if not self.done_after:
      while self.current_step().check():
        if not self.advance():
          self.mark_done()
          break

    return self.done_after

  def current_step(self):
    return self.steps[self._current_step]

  def on_final_step(self):
    return self._current_step == len(self.steps) - 1

  def advance(self):
    if self.on_final_step():
      return False
    else:
      prev_step = self.current_step()
      self._current_step += 1
      self.current_step().start_at = prev_step.done_by
      self._set_current_step_status(True)
      return True

  def mark_done(self):
    super(Ratchet, self).mark_done()
    self.done_after = self.steps[-1].done_after

  def _set_step_status(self, step, value):
    setattr(self._status, step.name, value)

  def _set_current_step_status(self, value):
    self._set_step_status(self.current_step(), value)
