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

"""Instalog Event flow policy.

Decides whether or not a plugin should process an Event.
"""

import logging


# Name of the key used to specify the rule type in the config dictionary.
_RULE_TYPE_KEY = 'rule'

# Registry to store a NAME => CLASS mapping of all the possible rules.
_rule_registry = {}


class FlowPolicy(object):
  """A flow policy defines a set of allow and deny rules for Events.

  An event *must* match one of the allow rules, and not match *any* of the
  deny rules in order to match.
  """

  def __init__(self, allow=None, deny=None):
    """Constructor.

    Args:
      allow: A list of dicts, where each dict must contain the key
            _RULE_TYPE_KEY ('rule').  The value of 'rule' corresponds to a Rule
            class's NAME member.  Other key-values are used as arguments for
            the particular rule in use.
      deny: See allow.
    """
    self.allow = [Rule.FromDict(dct) for dct in allow or []]
    self.deny = [Rule.FromDict(dct) for dct in deny or []]

  def MatchEvent(self, event):
    """Checks an Event against allow and deny rules."""
    allow = False
    for rule in self.allow:
      allow = allow or rule.MatchEvent(event)
    deny = False
    for rule in self.deny:
      deny = deny or rule.MatchEvent(event)
    return allow and not deny

  def __repr__(self):
    """Implements repr function for debugging."""
    return ('FlowPolicy(allow=%r, deny=%r)'
            % (self.allow, self.deny))


class RuleMeta(type):
  """Metaclass to collect FlowRule classes into a class registry."""

  def __new__(mcs, name, bases, class_dict):
    """Called when a class is defined."""
    cls = type.__new__(mcs, name, bases, class_dict)
    if hasattr(cls, 'NAME'):
      if cls.NAME in _rule_registry:
        raise RuntimeError('Multiple serializable classes with name "%s"'
                           % cls.__name__)
      _rule_registry[cls.NAME] = cls
    return cls


class Rule(object):
  """Superclass for rules which may or may not match an Event.

  Subclasses should define the constants NAME, KEYS, as well as the
  function MatchEvent.

  Properties:
    NAME: Defines the name of this rule.
    KEYS: Defines the names of arguments which may be provided to this rule.
          All arguments are optional.
  """

  __metaclass__ = RuleMeta

  def __init__(self, **kwargs):
    """Collects arguments into `args' member."""
    self.args = {}
    for key in self.KEYS:
      # All arguments are optional.  Ignore any missing ones.
      if key in kwargs:
        # Currently only the '==' operator is supported.
        self.args[key] = RHSOperation(kwargs.pop(key))
    if kwargs:
      raise ValueError('Extra arguments: %s' % kwargs)

  def __repr__(self):
    """Implements repr function for debugging."""
    return '%s(%r)' % (self.__class__.__name__, self.args)

  def __eq__(self, other):
    """Implements == operator."""
    return self.args == other.args

  @classmethod
  def FromDict(cls, dct):
    """Creates a rule from a configuration dict."""
    if _RULE_TYPE_KEY not in dct:
      raise ValueError('FlowPolicy: No `rule\' key found to specify rule type')
    rule_name = dct.pop(_RULE_TYPE_KEY)
    if rule_name not in _rule_registry:
      raise ValueError('FlowPolicy: No rule called `%s\'' % rule_name)
    return _rule_registry[rule_name](**dct)

  def MatchEvent(self, event):
    """Checks whether the provided event matches this rule."""
    raise NotImplementedError


class AllRule(Rule):
  """Allows any event."""

  NAME = 'all'
  KEYS = []

  def MatchEvent(self, event):
    """Checks whether the provided event matches this rule."""
    return True


class HistoryRule(Rule):
  """Checks for a particular entry in the Event's history."""

  NAME = 'history'
  KEYS = ['node_id', 'orig_time', 'time', 'plugin_id',
          'plugin_type', 'target', 'position']

  def MatchEvent(self, event):
    """Checks whether the provided event matches this rule."""
    for position, process_stage in enumerate(event.history):
      logging.debug('%s: %r', position, process_stage)

      valid = True
      for key, operation in self.args.iteritems():
        # Special case for the 'position' key.
        if key == 'position':
          lhs = position
          # If the specified position is negative, we need to
          # check against the negated index.
          if operation.rhs < 0:
            lhs -= len(event.history)
        else:
          lhs = getattr(process_stage, key)

        # Apply the operation to check the lhs.
        logging.debug('Checking %s %s...', lhs, operation)
        valid = valid and operation.Apply(lhs)
        if not valid:
          logging.debug('Short-circuit break')
          break

      if valid:
        logging.debug('Checked all arguments, matches')
        return True

    logging.debug('All history stages failed, no match')
    return False


class RHSOperation(object):
  """Represents an operator and a right-hand operand.

  Currently, the only supported operation is equality (==).
  """

  def __init__(self, rhs):
    """Constructor."""
    self.rhs = rhs

  def Apply(self, lhs):
    """Takes a right-hand operand and applies the operation."""
    return lhs == self.rhs

  def __repr__(self):
    """Implements repr function for debugging."""
    return 'RHSOperation(== %r)' % self.rhs

  def __eq__(self, other):
    """Implements == operator."""
    return self.rhs == other.rhs
