from threading import Lock
import inspect
import csv

from pyretic.examples.shared import *
from pyretic.lib.corelib import *
from pyretic.lib.std import *
from pyretic.lib.query import *
from pyretic.core.runtime import virtual_field

resourcesFile = "pyretic/examples/configs/resources.csv"
resourceRulesFile = "pyretic/examples/configs/firewall-resources.csv"

class firewall_resource(DynamicPolicy):
    def __init__(self):
        self.debug = 0
        self.resources = {}
        self.rules = {}
        self.loadResources()
        self.loadResourceRules()
        super(firewall_resource,self).__init__(true)
        self.update_policy()
    
    def addResource(self, resource, address):
        ip = None
        proto = None
        port = None
        
        if ":" in address:
            ip, proto, port = address.split(':')
        else:
            ip = address
        self.resources[resource].append((ip, proto, port))
    
    def loadResources(self):
        with open(resourcesFile, 'rb') as f:
            reader = csv.reader(f, delimiter=';')
            line = 0
            for row in reader:
                line = line + 1
                if line == 1:
                    continue
                
                self.resources[row[0]] = []
                
                if "," in row[1]:
                    for address in row[1].split(","):
                        self.addResource(row[0], address)
                else:
                    self.addResource(row[0], row[1])
    
    def loadResourceRules(self):
        with open(resourceRulesFile, 'rb') as f:
            reader = csv.reader(f, delimiter=';')
            line = 0
            for row in reader:
                line = line + 1
                if line == 1:
                    continue
                
                self.rules[row[0]] = []
                
                if "," in row[1]:
                    for group in row[1].split(","):
                        self.rules[row[0]].append(group)
                else:
                    self.rules[row[0]].append(row[1])
    
    def update_policy (self):
        self.policy = identity
        
        for port in portsList:
            deviceList = port["devices"] + [{'group': 'default'}]
            for device in deviceList:
                for rule in self.rules:
                    if "*" not in self.rules[rule] and device["group"] not in self.rules[rule]:
                        for resource in self.resources[rule]:
                            if resource[1] == "tcp":
                                numeric = 6;
                            elif resource[1] == "udp":
                                numeric = 17;
                            else:
                                numeric = 1
                            
                            self.policy = if_(match(switch=int(port["switch"]),port=int(port["port"]),group=device["group"],dstip=IPAddr(resource[0]),protocol=int(numeric),dstport=int(resource[2]),ethtype=IP_TYPE), drop, self.policy)
        
        if self.debug:
            print "firewall_resource POLICY", self.policy

def main():
    return firewall_resource()

