from pox.core import core
import pox
log = core.getLogger()

from pox.lib.recoco import Timer,Task,Sleep
import pox.lib.packet as pkt

import pox.openflow.libopenflow_01 as of

from pox.lib.revent import *

import time
count = []
global Connection

class MyTask (Task):
  '''
  global Connection 
  def __init__(self,connection):
    print "starting Task"
    Task.__init__(self,connection)
    self.connection=connection
    global Connection
    Connection = self.connection
  '''

  def run (self):
    print "starting run!!"
    def app(message,index):
      #match 
      vlanId_m=1234
      vlanPriority_m=6
      ethertype_m=0x801
      srcMac_m="00:11:22:33:44:55"
      dstMac_m="00:aa:bb:cc:dd:ee"
      in_port=2
      #action
      out_port=3
      vlanId_a=4094
      global count
      global Connection
      #run for all permutations of match using bit manipulation
      while (count[index] != 0):
  
        msg = of.ofp_flow_mod()
        match = of.ofp_match()

        
        if (count[index] & 1):
          match.dl_type=ethertype_m

        if (count[index] & 2):
          match.dl_vlan=vlanId_m

        if (count[index] & 4):
          match.dl_vlan_pcp = vlanPriority_m

        if (count[index] & 8):
          match.dl_dst = EthAddr(dstMac_m)

        if (count[index] & 16):
          match.dl_src = EthAddr(srcMac_m)

 
        msg.match = match
        msg.hard_timeout = 10
        if (message == "port"):
          msg.actions.append(of.ofp_action_output(port=out_port))
        elif (message == "controller"):
          msg.actions.append(of.ofp_action_output(port=of.OFPP_CONTROLLER))
        elif (message == "setvlanId"):
          msg.actions.append(of.ofp_action_vlan_vid(vlan_vid=vlanId_a))
          msg.actions.append(of.ofp_action_output(port=out_port))
        elif (message == "stripvlanId"):
          msg.actions.append(of.ofp_action_strip_vlan())
          msg.actions.append(of.ofp_action_output(port=out_port))
        print "Sending Flow"
        Connection.send(msg)
        print "flow Sent"
        count[index] -= 1
        print "Value of Count",count[index]
        yield Sleep(2)
        #if (count[index] == 0): return False

    global count
    match_count=3
    action_count=5
    count_m = pow(2,match_count)-1
    for i in range (0,action_count):
      count.append(count_m)
    print count
    #Timer(2, app, recurring = True, args=["port",0])
    #Timer(2, app, recurring = True, args=["controller",1]) 
    app("port",0)
    #yield Sleep(10)
    app("controller",1)

class my_learning (object):
  def __init__ (self):
    print 'init called'
    core.openflow.addListeners(self)

  def _handle_ConnectionUp (self, event):
    print 'Learning Switch to be called'
    log.debug("Connection %s" % (event.connection,))
    global Connection
    Connection = event.connection
    #t = MyTask(event.connection)
    t = MyTask()
    #t.start()

def launch ():
  print "calling launch"
  core.registerNew(my_learning)
