import unittest

class AddTest(unittest.TestCase):
    def setUp(self):
        #Set up the client
        from django.test.client import Client
        self.client = Client()
        
        #Set up the database
        from exodus import settings
        self.olddbname = settings.DATABASE_NAME
        from django.db import connection
        self.dbname = connection.creation.create_test_db(0)
        
        from exodus.models import Location

        self.location = Location(description = 'Hooigracht', \
            longitude = '45.675433', latitude = '56.543332')
        self.location.save()

    def tearDown(self):
        from django.db import connection
        connection.creation.destroy_test_db(self.olddbname, 0)

    def test_addlocation(self):
        post_data = {'description': 'JohnLaan2', 'longitude': '34.55', \
            'latitude' : '44.55', 'proceed': 'OK, proceed'}
        response = self.client.post('/add/location/new/', post_data) 

        self.failUnlessEqual(response.status_code, 302)
        self.failUnlessEqual(response['Location'], \
                'http://testserver/add/node/new/?location=2')

        from exodus.models import Location
    
        l = Location.objects.get(description = 'JohnLaan2')
        self.failUnless(str(l.longitude), '34.55')
        self.failUnless(str(l.latitude), '44.55')

    def test_addnode(self):
        post_data = {'name' : 'Tabitha', 'location' : 1, \
            'status' : 'up', 'network' : 1, 'proceed': 'OK, proceed'}
        response = self.client.post('/add/node/new/', post_data) 

        self.failUnlessEqual(response.status_code, 302)
        self.failUnlessEqual(response['Location'], \
                'http://testserver/view/node/Tabitha/')

        from exodus.models import Node
    
        try:
             n = Node.objects.get(name = 'Tabitha')
        except Node.DoesNotExist: 
            self.fail("Node wasn't added.")

        node = n 
        self.failUnlessEqual(n.location.id, 1)
        self.failUnlessEqual(n.status, 'up')
        self.failUnlessEqual(n.network.id, 1) 

        c = {}

        for i in n.as_list():
           c[i[0]] = i[1] 

        self.failUnless(c.has_key('masterip'))

class wllogic(unittest.TestCase):
    def setUp(self):
        #Set up the client
        from django.test.client import Client
        self.client = Client()
        
        #Set up the database
        from django.db import connection
        from exodus import settings
        self.olddbname = settings.DATABASE_NAME
        self.dbname = connection.creation.create_test_db(0)

    def tearDown(self):
        from django.db import connection
        connection.creation.destroy_test_db(self.olddbname, 0)

    def test_new_SSID_name(self):
        class node(object):
            name = 'CeTIM'
            class network(object):
                name = 'wleiden.net'
        nic = 'ath0'
        desc = '2cope'
        from exodus.wllogic import newSSIDName
        ssid = newSSIDName(node(), nic, desc)        
        
        self.failUnless(ssid, '2cope-ath0.CeTIM.wleiden.net')

    def test_parse_show_addr(self):
        ip = '172.16.2.0'
        from exodus.wllogic import parse_addr
        parsed = parse_addr(ip)
        self.failUnlessEqual(str(parsed), '2886730240')

        from exodus.wllogic import show_addr
        o_ip = show_addr(parsed)
        self.failUnlessEqual(o_ip, ip)

        # when using an address larger then 256, move 1 address up.
        ip = '172.16.2.256'
        o_ip = show_addr(parse_addr(ip))
        self.failUnlessEqual(o_ip, '172.16.3.0')

    def test_netmask2subnet(self):
        from wllogic import netmask2subnet

        self.failUnlessRaises(ValueError, netmask2subnet, 33)
        self.failUnlessRaises(ValueError, netmask2subnet, -1)

        valid_subnet = netmask2subnet(30)
        self.failUnlessEqual(str(valid_subnet), '17179869180')
    
    def test_getSubnet(self):
        from wllogic import getSubnet
        self.failUnlessRaises(ValueError, getSubnet, -1)
        self.failUnlessRaises(ValueError, getSubnet, 33)
        
        valid_netmask = getSubnet(30)
        self.failUnless(valid_netmask, '255.255.255.252')
    
    def test_network(self):
        from wllogic import network
        from wllogic import show_addr
        network_addr = show_addr(network('172.18.5.10', 24))
        self.failUnlessEqual(network_addr, '172.18.5.0')

    def test_broadcast(self):
        from wllogic import broadcast
        from wllogic import show_addr
        
        broadcast_addr = show_addr(broadcast('172.16.5.232', 24))
        self.failUnlessEqual(broadcast_addr, '172.16.5.255')

        self.failUnlessRaises(ValueError, broadcast, '172.16.5.1', -1)
        self.failUnlessRaises(ValueError, broadcast, '172.16.5.1', 33)
    
    def test_getNetwork(self):
        from wllogic import getNetwork
        network_addr = getNetwork('172.17.2.2', 30)
        self. failUnlessEqual(network_addr, '172.17.2.0')

        self.failUnlessRaises(ValueError, getNetwork, '172.17.2.0', -1)
        self.failUnlessRaises(ValueError, getNetwork, '172.17.2.0', 33)

    def test_getBroadcast(self):
        from wllogic import getBroadcast
        broadcast_addr = getBroadcast('172.17.2.2', 24)
        self.failUnlessEqual(broadcast_addr, '172.17.2.255')
        
        self.failUnlessRaises(ValueError, getBroadcast, '172.17.2.0', -1)
        self.failUnlessRaises(ValueError, getBroadcast, '172.17.2.0', 33)

    def test_free_masterip(self):
        from wllogic import free_masterip
        from exodus.models import Node, Network

        node = Node.objects.create(location_id = 1, \
                masterip = '172.16.0.1', name = 'testnode')
        network = Network.objects.get(pk=1)
        ip = free_masterip(network) 
        self.failIfEqual(ip, '172.16.0.1') 
        self.failUnlessEqual(ip, '172.16.1.1')
        
    def test_freePublicAPIP(self):
        from wllogic import freePublicAPIP
        self.fail('test not implemented')

    def test_freeInterlinkIP(self):
        from wllogic import freeInterlinkIP
        self.fail('Test not implemented')

    def test_addInterlinkIP(self):
        from wllogic import addInterlinkIP
        self.fail('Test not implemented')

class Link(unittest.TestCase):
    def setUp(self):
        class link(object):
            def __init__(self, type, node):
                self.type = type
                self.node = node

        self.link00 = link('eth', 1)
        self.link01 = link('eth', 2)
        self.link10 = link('11a', 1)
        self.link11 = link('11a', 2)
        self.link20 = link('11b', 1)
        self.link21 = link('11b', 2)
        self.link30 = link('11g', 1)		
        self.link31 = link('11g', 2)

    def test_link_has_compat_type(self):
        from wllogic import link_has_compat_type
       
        # test link to self
        self.failUnless(link_has_compat_type(self.link00, self.link00))
        # test eth
        self.failUnless(link_has_compat_type(self.link00, self.link01))
        # test 11a
        self.failUnless(link_has_compat_type(self.link10, self.link11))
        # test 11b
        self.failUnless(link_has_compat_type(self.link20, self.link21))
        # test 11g
        self.failUnless(link_has_compat_type(self.link30, self.link31))
        # test 11b vs 11g
        self.failUnless(link_has_compat_type(self.link20, self.link30))
        self.failUnless(link_has_compat_type(self.link30, self.link20))

        # test fail eth vs 11a
        self.failIf(link_has_compat_type(self.link00, self.link10))
        # test fail eth vs 11b
        self.failIf(link_has_compat_type(self.link00, self.link20))
        # test fail eth vs 11g
        self.failIf(link_has_compat_type(self.link00, self.link30))
        # test fail 11a vs 11b
        self.failIf(link_has_compat_type(self.link10, self.link20))
        # test fail 11a vs 11g
        self.failIf(link_has_compat_type(self.link10, self.link30))
    
    def test_link_not_same_node(self):
        from wllogic import link_is_not_to_itself
        self.failUnless(link_is_not_to_itself(self.link00, self.link01))
        self.failIf(link_is_not_to_itself(self.link20, self.link30))
    
    def test_link_is_wireless(self):
        from wllogic import link_is_wireless
        self.failIf(link_is_wireless(self.link00))
        self.failUnless(link_is_wireless(self.link10))
        self.failUnless(link_is_wireless(self.link20))
        self.failUnless(link_is_wireless(self.link30))
		
def suite():
    s = unittest.TestSuite()
    s.addTest(unittest.makeSuite(AddTest))
    s.addTest(unittest.makeSuite(wllogic))
    s.addTest(unittest.makeSuite(Link))

    return s
