# Copyright 2011 James McCauley
#
# This file is part of POX.
#
# POX is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# POX is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with POX.  If not, see <http://www.gnu.org/licenses/>.

"""
Some of POX's core API and functionality is here, largely in the POXCore
class (an instance of which is available as pox.core.core).

This includes things like component rendezvous, logging, system status
(up and down events), etc.
"""

# Set up initial log state
import logging

import inspect
import time
import os

_path = inspect.stack()[0][1]
_ext_path = _path[0:_path.rindex(os.sep)]
_ext_path = os.path.dirname(_ext_path) + os.sep
_path = os.path.dirname(_path) + os.sep

SQUELCH_TIME = 5

_squelch = ''
_squelchTime = 0
_squelchCount = 0

def getLogger (name=None, moreFrames=0):
  """
  In general, you don't need to call this directly, and will use
  core.getLogger() instead.
  """
  if name is None:
    s = inspect.stack()[1+moreFrames]
    name = s[1]
    if name.endswith('.py'):
      name = name[0:-3]
    elif name.endswith('.pyc'):
      name = name[0:-4]
    if name.startswith(_path):
      name = name[len(_path):]
    elif name.startswith(_ext_path):
      name = name[len(_ext_path):]
    name = name.replace('/', '.').replace('\\', '.') #FIXME: use os.path or whatever

    # Remove double names ("topology.topology" -> "topology")
    if name.find('.') != -1:
      n = name.split('.')
      if len(n) >= 2:
        if n[-1] == n[-2]:
          del n[-1]
          name = '.'.join(n)

    if name.endswith(".__init__"):
      name = name.rsplit(".__init__",1)[0]

  l = logging.getLogger(name)
  g=globals()
  if not hasattr(l, "print"):
    def printmsg (*args, **kw):
      #squelch = kw.get('squelch', True)
      msg = ' '.join((str(s) for s in args))
      s = inspect.stack()[1]
      o = '['
      if 'self' in s[0].f_locals:
        o += s[0].f_locals['self'].__class__.__name__ + '.'
      o += s[3] + ':' + str(s[2]) + '] '
      o += msg
      if o == _squelch:
        if time.time() >= _squelchTime:
          l.debug("[Previous message repeated %i more times]" % (g['_squelchCount']+1,))
          g['_squelchCount'] = 0
          g['_squelchTime'] = time.time() + SQUELCH_TIME
        else:
          g['_squelchCount'] += 1
      else:
        g['_squelch'] = o
        if g['_squelchCount'] > 0:
          l.debug("[Previous message repeated %i more times]" % (g['_squelchCount'],))
        g['_squelchCount'] = 0
        g['_squelchTime'] = time.time() + SQUELCH_TIME
        l.debug(o)

    setattr(l, "print", printmsg)
    setattr(l, "msg", printmsg)

  return l


log = (lambda : getLogger())()

from pox.lib.revent import *

# Now use revent's exception hook to put exceptions in event handlers into
# the log...
def _revent_exception_hook (source, event, args, kw, exc_info):
  try:
    c = source
    t = event
    if hasattr(c, "__class__"): c = c.__class__.__name__
    if isinstance(t, Event): t = t.__class__.__name__
    elif issubclass(t, Event): t = t.__name__
  except:
    pass
  log.exception("Exception while handling %s!%s...\n" % (c,t))
import pox.lib.revent.revent
pox.lib.revent.revent.handleEventException = _revent_exception_hook

class GoingUpEvent (Event):
  """ Fired when system is going up. """
  pass

class GoingDownEvent (Event):
  """ Fired when system is going down. """
  pass

class UpEvent (Event):
  """ Fired when system is up. """
  pass

class DownEvent (Event):
  """ Fired when system is down. """
  pass

class ComponentRegistered (Event):
  """
  This is raised by core whenever a new component is registered.
  By watching this, a component can monitor whether other components it
  depends on are available.
  """
  def __init__ (self, name, component):
    Event.__init__(self)
    self.name = name
    self.component = component

import pox.lib.recoco as recoco

class POXCore (EventMixin):
  """
  A nexus of of the POX API.

  pox.core.core is a reference to an instance of this class.  This class
  serves a number of functions.

  An important one is that it can serve as a rendezvous point for
  components.  A component can register objects on core, and they can
  then be accessed on the core object (e.g., if you register foo, then
  there will then be a pox.core.core.foo).  In many cases, this means you
  won't need to import a module.

  Another purpose to the central registration is that it decouples
  functionality from a specific module.  If myL2Switch and yourL2Switch
  both register as "switch" and both provide the same API, then it doesn't
  matter.  Doing this with imports is a pain.

  Additionally, a number of commmon API functions are vailable here.
  """
  _eventMixin_events = set([
    UpEvent,
    DownEvent,
    GoingUpEvent,
    GoingDownEvent,
    ComponentRegistered
  ])

  def __init__ (self):
    self.debug = False
    self.running = True
    self.components = {}

    self.version = (0,0,0)
    print "{0} / Copyright 2011 James McCauley".format(self.version_string)

    self.scheduler = recoco.Scheduler(daemon=True)

  @property
  def version_string (self):
    return "POX " + '.'.join(map(str, self.version))

  def callDelayed (_self, _seconds, _func, *args, **kw):
    """
    Calls the function at a later time.
    This is just a wrapper around a recoco timer.
    """
    t = recoco.Timer(_seconds, _func, args=args, kw=kw,
                     scheduler = _self.scheduler)
    return t

  def callLater (_self, _func, *args, **kw):
    # first arg is `_self` rather than `self` in case the user wants
    # to specify self as a keyword argument
    """
    Call the given function with the given arguments within the context
    of the co-operative threading environment.
    It actually calls it sooner rather than later. ;)
    Much of POX is written without locks because it's all thread-safe
    with respect to itself, as it's written using the recoco co-operative
    threading library.  If you have a real thread outside of the
    co-operative thread context, you need to be careful about calling
    things within it.  This function provides a rather simple way that
    works for most situations: you give it a callable (like a method)
    and some arguments, and it will call that callable with those
    arguments from within the co-operative threader, taking care of
    synchronization for you.
    """
    _self.scheduler.callLater(_func, *args, **kw)

  def raiseLater (_self, _obj, *args, **kw):
    # first arg is `_self` rather than `self` in case the user wants
    # to specify self as a keyword argument
    """
    This is similar to callLater(), but provides an easy way to raise a
    revent event from outide the co-operative context.
    Rather than foo.raiseEvent(BarEvent, baz, spam), you just do
    core.raiseLater(foo, BarEvent, baz, spam).
    """
    _self.scheduler.callLater(_obj.raiseEvent, *args, **kw)

  def getLogger (self, *args, **kw):
    """
    Returns a logger.  Pass it the name you want if you'd like to specify
    one (e.g., core.getLogger("foo")).  If you don't specify a name, it
    will make one up based on the module name it is called from.
    """
    return getLogger(moreFrames=1,*args, **kw)

  def quit (self):
    """
    Shut down POX.
    """
    if self.running:
      self.running = False
      log.info("Going down...")
      import gc
      gc.collect()
      self.raiseEvent(GoingDownEvent())
      self.callLater(self.scheduler.quit)
      for i in range(50):
        if self.scheduler._hasQuit: break
        gc.collect()
        time.sleep(.1)
      if not self.scheduler._allDone:
        log.warning("Scheduler didn't quit in time")
      self.raiseEvent(DownEvent())
      log.info("Down.")

  def goUp (self):
    log.debug(self.version_string + " going up...")

    import platform
    py = "{impl} ({vers}/{build})".format(
     impl=platform.python_implementation(),
     vers=platform.python_version(),
     build=platform.python_build()[1].replace("  "," "))
    log.debug("Running on " + py)

    self.raiseEvent(GoingUpEvent())
    log.info(self.version_string + " is up.")
    self.raiseEvent(UpEvent())

  def hasComponent (self, name):
    """
    Returns True if a component with the given name has been registered.
    """
    return name in self.components

  def registerNew (self, __componentClass, *args, **kw):
    """
    Give it a class (and optional __init__ arguments), and it will
    create an instance and register it using the class name.  If the
    instance has a _core_name property, it will use that instead.
    It returns the new instance.
    core.registerNew(FooClass, arg) is roughly equivalent to
    core.register("FooClass", FooClass(arg)).
    """
    name = __componentClass.__name__
    obj = __componentClass(*args, **kw)
    if hasattr(obj, '_core_name'):
      # Default overridden
      name = obj._core_name
    self.register(name, obj)
    return obj

  def register (self, name, component):
    """
    Makes the object "component" available as pox.core.core.name.
    """
    #TODO: weak references?
    if name in self.components:
      log.warn("Warning: Registered '%s' multipled times" % (name,))
    self.components[name] = component
    self.raiseEventNoErrors(ComponentRegistered, name, component)

  def listenToDependencies(self, sink, components):
    """
    If a component depends on having other components
    registered with core before it can boot, it can use this method to
    check for registration, and listen to events on those dependencies.

    Note that event handlers named with the _handle* pattern in the sink must
    include the name of the desired source as a prefix. For example, if topology is a
    dependency, a handler for topology's SwitchJoin event must be labeled:
       def _handle_topology_SwitchJoin(...)

    sink - the component waiting on dependencies
    components - a list of dependent component names

    Returns whether all of the desired components are registered.
    """
    if components == None or len(components) == 0:
      return True

    got = set()
    for c in components:
      if self.hasComponent(c):
        setattr(sink, c, getattr(self, c))
        sink.listenTo(getattr(self, c), prefix=c)
        got.add(c)
      else:
        setattr(sink, c, None)
    for c in got:
      components.remove(c)
    if len(components) == 0:
      log.debug(sink.__class__.__name__ + " ready")
      return True
    return False

  def __getattr__ (self, name):
    if name not in self.components:
      raise AttributeError("'%s' not registered" % (name,))
    return self.components[name]

core = POXCore()
