""" Test package of NIDs """
# Copyright (C) 2013 Libor Polčák
#
# This program 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.
#
# This program 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 this program.  If not, see <http://www.gnu.org/licenses/>.

import unittest
import IPy

from modules.shared.nid import *

class Tests(unittest.TestCase):

    def testCreateNID(self):
        test_vector = (
                ("147.229.1.1", "IPv4", IPy.IP("147.229.1.1")),
                ("147.229.1.1/32", "IPv4", IPy.IP("147.229.1.1/32")),
                ("147.229.0.0/16", "IPv4", IPy.IP("147.229.0.0/16")),
                ("2001:db8::/32", "IPv6", IPy.IP("2001:db8::/32")),
                ("2001:db8::/64", "IPv6", IPy.IP("2001:db8::/64")),
                ("2001:db8::/128", "IPv6", IPy.IP("2001:db8::/128")),
                ("2001:db8::1", "IPv6", IPy.IP("2001:db8::1")),
                ("00:00:00:00:00:00", "MAC", "00:00:00:00:00:00"),
                ("00-00-00-00-00-00", "MAC", "00:00:00:00:00:00"),
                ("ppp:test_login", "PPP Login", "test_login"),
                ("ppp:test_login:", "PPP Login", "test_login:"),
                ("radius:login", "Radius Login", "login"),
                ("radius:login::", "Radius Login", "login::"),
                ("radius:login:33:44:55:66", "Radius Login", "login:33:44:55:66"),
                ("ppps:0x123456", "PPP Session", "0x123456"),
                ("duid:duid", "DUID", "duid"),
                ("dhcpClientID:0x123456", "DHCP client ID", "0x123456"),
                ("ymsgLogin:standa4", "YMSG LOGIN", "standa4"),
                ("oscarLogin:standa4", "OSCAR LOGIN", "standa4"),
                ("ircLogin:standa4", "IRC LOGIN", "standa4"),
                ("xmppLogin:standa4@jabber.fit.vutbr.cz", "XMPP LOGIN", "standa4@jabber.fit.vutbr.cz"),
                ("xmppLogin:standa4@jabber.fit.vutbr.cz/doma", "XMPP LOGIN",
                    "standa4@jabber.fit.vutbr.cz/doma"),
                ("ircChannel:#sec6net", "IRC CHANNEL", "#sec6net"),
            )
        for n, t, v in test_vector:
            nn = CreateNID(n)
            tt = nn.getType()
            vv = nn.getValue()
            oo = CreateNID(str(nn))
            self.assertEqual(tt, t, (n, tt, t))
            self.assertEqual(vv, v, (n, vv, v))
            self.assertEqual(oo, nn)
            self.assertTrue(oo in nn)
            self.assertTrue(nn in oo)

    def testIPv4Operations(self):
        top = CreateNID("0.0.0.0/0")
        classA = CreateNID("10.0.0.0/8")
        classB = CreateNID("10.10.0.0/16")
        classC = CreateNID("10.10.10.0/24")
        full = CreateNID("10.10.10.10")
        full2 = CreateNID("10.10.10.10/32")
        self.assertEqual(full, full2)
        #-
        self.assertTrue(full in top)
        self.assertTrue(classC in top)
        self.assertTrue(classB in top)
        self.assertTrue(classA in top)
        self.assertTrue(top in top)
        #-
        self.assertTrue(full in classA)
        self.assertTrue(classC in classA)
        self.assertTrue(classB in classA)
        self.assertTrue(classA in classA)
        self.assertTrue(top not in classA)
        #-
        self.assertTrue(full in classB)
        self.assertTrue(classC in classB)
        self.assertTrue(classB in classB)
        self.assertTrue(classA not in classB)
        self.assertTrue(top not in classB)
        #-
        self.assertTrue(full in classC)
        self.assertTrue(classC in classC)
        self.assertTrue(classB not in classC)
        self.assertTrue(classA not in classC)
        self.assertTrue(top not in classC)
        #-
        self.assertTrue(full in full)
        self.assertTrue(classC not in full)
        self.assertTrue(classB not in full)
        self.assertTrue(classA not in full)
        self.assertTrue(top not in full)

    def testIPv4Operations(self):
        top = CreateNID("::/0")
        classA = CreateNID("2001:db8::/32")
        classB = CreateNID("2001:db8:1234::/48")
        classC = CreateNID("2001:db8:1234:5678::/64")
        full = CreateNID("2001:db8:1234:5678::1")
        full2 = CreateNID("2001:db8:1234:5678::1/128")
        self.assertEqual(full, full2)
        #-
        self.assertTrue(full in top)
        self.assertTrue(classC in top)
        self.assertTrue(classB in top)
        self.assertTrue(classA in top)
        self.assertTrue(top in top)
        #-
        self.assertTrue(full in classA)
        self.assertTrue(classC in classA)
        self.assertTrue(classB in classA)
        self.assertTrue(classA in classA)
        self.assertTrue(top not in classA)
        #-
        self.assertTrue(full in classB)
        self.assertTrue(classC in classB)
        self.assertTrue(classB in classB)
        self.assertTrue(classA not in classB)
        self.assertTrue(top not in classB)
        #-
        self.assertTrue(full in classC)
        self.assertTrue(classC in classC)
        self.assertTrue(classB not in classC)
        self.assertTrue(classA not in classC)
        self.assertTrue(top not in classC)
        #-
        self.assertTrue(full in full)
        self.assertTrue(classC not in full)
        self.assertTrue(classB not in full)
        self.assertTrue(classA not in full)
        self.assertTrue(top not in full)

    def testEmailMsg(self):
        msg = CreateNIDType((('E-mail address', 'gurpartap@patriots.in'),[('E-mail address', ' <raj_deol2002in@yahoo.co.in')],('E-mail Message-ID', 'unknown')), "E-mail message")
        self.assertEqual(msg.getType(), "E-mail message")
        
    def testTCPSyntax(self):
        a = CreateNIDType(("1.1.1.1", 11, "2.2.2.2", 22), "TCP")
        b = CreateNID('tcp:("1.1.1.1", 11, "2.2.2.2", 22)')        
        c = CreateNID('tcp:(\'1.1.1.1\', 11, \'2.2.2.2\', 22)')
        d = CreateNID('tcp:(1.1.1.1, 11, 2.2.2.2, 22)')
        
        self.assertEqual(str(a), str(b))
        self.assertEqual(str(a), str(c))
        self.assertEqual(str(a), str(d))
        
        x = CreateNID('tcp3:10.0.2.15_50329')
        y = CreateNIDType("10.0.2.15_50329", "TCP3")
        self.assertEqual(str(x), str(y))

    def testGetSubNIDsAtomic(self):
        self.assertFalse(CreateNID("1.2.3.4").getSubNIDs())
        self.assertFalse(CreateNID("00:11:22:33:44:55").getSubNIDs())
        self.assertFalse(CreateNID("2001:db8::22:33:44:55").getSubNIDs())
        self.assertFalse(CreateNID("ppp:a").getSubNIDs())
        self.assertFalse(CreateNID("ppps:a").getSubNIDs())
        self.assertFalse(CreateNID("duid:a").getSubNIDs())
        self.assertFalse(CreateNID("dhcpClientID:a").getSubNIDs())
        self.assertFalse(CreateNID("ircChannel:a").getSubNIDs())
        self.assertFalse(CreateNID("sdnConnector:OF_00:00:00:00:00:00:00:03_1").getSubNIDs())

    def testGetSubNIDsEmail(self):
        sender = 'example@sec6net'
        receivers = ('receiver1@sec6net', 'receiver2@sec6net')
        msgid = 'id'
        e = CreateNID("emailmsg:(('E-mail address', %s), %s, ('E-mail Message-ID', %s))" % \
                (repr(sender),
                 repr(tuple(('E-mail address', r) for r in receivers)),
                 repr(msgid)))
        expected = [CreateNID("email:" + sender), CreateNID("emailmsgid:" + msgid)]
        for recv in receivers:
            expected.append(CreateNID("email:" + recv))
        returned = e.getSubNIDs()
        for i in expected:
            self.assertTrue(i in returned, (returned, expected))
        for i in returned:
            self.assertTrue(i in expected, (returned, expected))

    def testGetSubNIDsTCP(self):
        senderIP = "1.2.3.4"
        receiverIP = "5.6.7.8"
        senderPort = 1234
        recevierPort = 5678
        t = CreateNID("tcp:(%s, %d, %s, %d)" % (repr(senderIP), senderPort, repr(receiverIP),
            recevierPort))
        expected = [CreateNID(senderIP), CreateNID(receiverIP)]
        returned = t.getSubNIDs()
        for i in expected:
            self.assertTrue(i in returned, (returned, expected))
        for i in returned:
            self.assertTrue(i in expected, (returned, expected))

    def testGetSubNIDsTCP3(self):
        senderIP = "1.2.3.4"
        senderPort = 1234
        t = CreateNID("tcp3:%s_%d" % (senderIP, senderPort))
        expected = [NIDIP(senderIP)]
        returned = t.getSubNIDs()
        for i in expected:
            self.assertTrue(i in returned, (returned, expected))
        for i in returned:
            self.assertTrue(i in expected, (returned, expected))

    def testGetSubNIDsUDP(self):
        senderIP = "1.2.3.4"
        receiverIP = "5.6.7.8"
        senderPort = 1234
        recevierPort = 5678
        t = CreateNID("udp:(%s, %d, %s, %d)" % (repr(senderIP), senderPort, repr(receiverIP),
            recevierPort))
        expected = [CreateNID(senderIP), CreateNID(receiverIP)]
        returned = t.getSubNIDs()
        for i in expected:
            self.assertTrue(i in returned, (returned, expected))
        for i in returned:
            self.assertTrue(i in expected, (returned, expected))

    def testGetSubNIDsUDP3(self):
        senderIP = "1.2.3.4"
        senderPort = 1234
        t = CreateNID("udp3:%s_%d" % (senderIP, senderPort))
        expected = [NIDIP(senderIP)]
        returned = t.getSubNIDs()
        for i in expected:
            self.assertTrue(i in returned, (returned, expected))
        for i in returned:
            self.assertTrue(i in expected, (returned, expected))



def suite():
	test = unittest.makeSuite(Tests, "test")
	return unittest.TestSuite(tuple(test))

def test():
	runner = unittest.TextTestRunner()
	runner.run(suite())

