#!/bin/env python

import sys
sys.path.append('.')

from sim.api import *
from sim.basics import *
import sim.topo as topo
import os
import time

# change accordingly for different types of switch desired for testing
from hub import Hub
from learning_switch import LearningSwitch
from rip_router import RIPRouter

# the switch type to be used for this test
SwitchType = Hub

def main():
  # A list of host names to be created
  create_host_requests = []
  # A list of switch names to be created
  create_switch_requests = []
  
  # A list of tuples where each (a, b, sec)
  # indicates: node a connects with node b after sec time
  link_requests = []
  # A list of tuples where each (a, b, sec)
  # indicates: node a disconnects with node b after sec time
  unlink_requests = []
  
  # A list of tuples, (src, dst, sec) such that src pings dst
  ping_requests = []
  
  # A dictionary of all Entity(base or sub class) objects created
  entities = {}
  
  
  if len(sys.argv) < 2:
      print >>sys.stderr, str.format("Usage: python {0} file", sys.argv[0])
      sys.exit(1)
  elif len(sys.argv) <= 2:
      try:
          f = open(sys.argv[1], 'r')
      except:
          print 'Error in opening file: ' + sys.argv[1]
          exit()
      if os.stat(sys.argv[1])[6]==0: # if linkSchedule file is empty
          print 'Link schedule file is empty'
      else:
          for line in f:
              words_lst = line.strip().split()
              if words_lst[0] == 'create':
                  if words_lst[1] == 'host':
                      create_host_requests.append(words_lst[2])
                  elif words_lst[1] == 'switch':
                      create_switch_requests.append(words_lst[2])
                  else:
                      print 'Error in creating entity: %s' %words_lst[1]
                      exit(1)
              elif words_lst[0] == 'ping':
                  if len(words_lst) == 3:
                      ping_requests.append((words_lst[1], words_lst[2], 0))
                  elif len(words_lst) == 4:
                      ping_requests.append((words_lst[1], words_lst[2], words_lst[3]))
                  else:
                      print 'Wrote file format: %' %line
                      exit(1)
              elif words_lst[0] == 'link':
                  if len(words_lst) == 3: # instant link, i.e., link h1 h2
                      link_requests.append((words_lst[1], words_lst[2], 0))
                  elif len(words_lst) == 4: # sheduled link, i.e., link h1 h2 5
                      link_requests.append((words_lst[1], words_lst[2], words_lst[3]))
                  else:
                      print 'Wrong file format: %' %line
                      exit(1)
              elif words_lst[0] == 'unlink':
                  if len(words_lst) == 3: # instant unlink, i.e., unlink h1 h2
                      unlink_requests.append((words_lst[1], words_lst[2], 0))
                  elif len(words_lst) == 4: # sheduled unlink, i.e., unlink h1 h2 5
                      unlink_requests.append((words_lst[1], words_lst[2], words_lst[3]))
                  else:
                      print 'Wrong file format: %' %line
                      exit(1)
              else:
                  print 'Unknown operation: %s' %line[0]
                  exit(1)
      try:
          f.close()
      except:
          print 'Error in closing file: ' + sys.argv[1]
          exit()

  api.simlog.setLevel(logging.DEBUG)
  api.userlog.setLevel(logging.DEBUG)
  
  create_topology(create_host_requests, create_switch_requests, entities)
  execute_link_schedules(link_requests, unlink_requests, entities)
  
  execute_ping_requests(ping_requests, entities)
  start = sim.core.simulate
  # Change True to False to run in non-interactive mode
  start(True)
  # Comment out if running in non-interactive mode
  import code
  code.interact(local=locals(), banner='')

# Creates a specified topology
def create_topology(create_host_requests, create_switch_requests, entities):
    '''
    Create a simple topology based on the file
    '''
    if len(create_host_requests) != 0:
        for h in create_host_requests:
            entities[h] = BasicHost.create(h)
    if len(create_switch_requests) != 0:
        for s in create_switch_requests:
            entities[s] = SwitchType.create(s)

def execute_link_schedules(link_requests, unlink_requests, entities):
    if len(link_requests) != 0:
        for l in link_requests:
            topo.link_later(entities[l[0]], entities[l[1]], float(l[2]))
    if len(unlink_requests) != 0:
        for l in unlink_requests:
            topo.unlink_later(entities[l[0]], entities[l[1]], float(l[2]))

import sim.api as api
import logging
import sim.core

def execute_ping_requests(ping_requests, entities):
    if len(ping_requests) != 0:
        for r in ping_requests:
            sim.core.Ping(entities[r[0]], entities[r[1]], float(r[2]))

if __name__ == "__main__":
    main()
